diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 0a499f3..5997ef2 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -29,6 +29,17 @@ public function getConfigTreeBuilder() $treeBuilder->root('task') ->children() ->enumNode('storage')->values(['array', 'doctrine'])->defaultValue('doctrine')->end() + ->arrayNode('adapters') + ->addDefaultsIfNotSet() + ->children() + ->arrayNode('doctrine') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('clear')->defaultTrue()->end() + ->end() + ->end() + ->end() + ->end() ->arrayNode('run') ->addDefaultsIfNotSet() ->children() diff --git a/src/DependencyInjection/TaskExtension.php b/src/DependencyInjection/TaskExtension.php index 1d7af6b..9fd77aa 100644 --- a/src/DependencyInjection/TaskExtension.php +++ b/src/DependencyInjection/TaskExtension.php @@ -13,9 +13,13 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Task\Event\Events; +use Task\TaskBundle\EventListener\DoctrineTaskExecutionListener; /** * Container extension for php-task library. @@ -40,12 +44,27 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('listener.xml'); } - if ('doctrine' === $config['storage']) { - // FIXME move to compiler pass - $container->getDefinition('task.command.schedule_task') - ->addArgument(new Reference('doctrine.orm.entity_manager')); - $container->getDefinition('task.command.run') - ->addArgument(new Reference('doctrine.orm.entity_manager')); + $this->loadDoctrineAdapter($config['adapters']['doctrine'], $container); + } + + /** + * Load doctrine adapter. + * + * @param array $config + * @param ContainerBuilder $container + */ + private function loadDoctrineAdapter(array $config, ContainerBuilder $container) + { + if ($config['clear']) { + $definition = new Definition( + DoctrineTaskExecutionListener::class, + [new Reference('doctrine.orm.entity_manager', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)] + ); + $definition->addTag( + 'kernel.event_listener', + ['event' => Events::TASK_AFTER, 'method' => 'clearEntityManagerAfterTask'] + ); + $container->setDefinition('task.adapter.doctrine.execution_listener', $definition); } } } diff --git a/src/Entity/TaskExecutionRepository.php b/src/Entity/TaskExecutionRepository.php index c71999d..560ffe6 100644 --- a/src/Entity/TaskExecutionRepository.php +++ b/src/Entity/TaskExecutionRepository.php @@ -89,6 +89,22 @@ public function findPending(TaskInterface $task) } } + /** + * {@inheritdoc} + */ + public function findByUuid($uuid) + { + try { + return $this->createQueryBuilder('e') + ->where('e.uuid = :uuid') + ->setParameter('uuid', $uuid) + ->getQuery() + ->getSingleResult(); + } catch (NoResultException $e) { + return; + } + } + /** * {@inheritdoc} */ diff --git a/src/EventListener/DoctrineTaskExecutionListener.php b/src/EventListener/DoctrineTaskExecutionListener.php new file mode 100644 index 0000000..8979876 --- /dev/null +++ b/src/EventListener/DoctrineTaskExecutionListener.php @@ -0,0 +1,48 @@ +entityManager = $entityManager; + } + + /** + * This method clears the entity-manager after each task to ensure clean state before next task. + * + * @param TaskExecutionEvent $event + */ + public function clearEntityManagerAfterTask(TaskExecutionEvent $event) + { + if (!$this->entityManager) { + return; + } + + $this->entityManager->clear(); + } +} diff --git a/src/Resources/config/task_event_listener.xml b/src/Resources/config/task_event_listener.xml index 23a08f9..184eb25 100644 --- a/src/Resources/config/task_event_listener.xml +++ b/src/Resources/config/task_event_listener.xml @@ -7,6 +7,7 @@ Task\Event\Events::TASK_CREATE Task\Event\Events::TASK_EXECUTION_CREATE Task\Event\Events::TASK_BEFORE + Task\Event\Events::TASK_AFTER Task\Event\Events::TASK_FINISHED Task\Event\Events::TASK_PASSED Task\Event\Events::TASK_FAILED diff --git a/tests/Functional/Command/RunCommandTest.php b/tests/Functional/Command/RunCommandTest.php index 87adbac..3989997 100644 --- a/tests/Functional/Command/RunCommandTest.php +++ b/tests/Functional/Command/RunCommandTest.php @@ -42,21 +42,24 @@ public function testExecute() ] ); - $this->assertEquals(TaskStatus::COMPLETED, $executions[0]->getStatus()); - $this->assertEquals(strrev('Test workload 1'), $executions[0]->getResult()); - $this->assertGreaterThan(0, $executions[0]->getDuration()); - $this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime()); - - $this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus()); - $this->assertNull($executions[1]->getResult()); - $this->assertNull($executions[1]->getDuration()); - $this->assertNull($executions[1]->getStartTime()); - $this->assertNull($executions[1]->getEndTime()); - - $this->assertEquals(TaskStatus::COMPLETED, $executions[2]->getStatus()); - $this->assertEquals(strrev('Test workload 3'), $executions[2]->getResult()); - $this->assertGreaterThan(0, $executions[2]->getDuration()); - $this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime()); + $execution = $this->taskExecutionRepository->findByUuid($executions[0]->getUuid()); + $this->assertEquals(TaskStatus::COMPLETED, $execution->getStatus()); + $this->assertEquals(strrev('Test workload 1'), $execution->getResult()); + $this->assertGreaterThan(0, $execution->getDuration()); + $this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime()); + + $execution = $this->taskExecutionRepository->findByUuid($executions[1]->getUuid()); + $this->assertEquals(TaskStatus::PLANNED, $execution->getStatus()); + $this->assertNull($execution->getResult()); + $this->assertNull($execution->getDuration()); + $this->assertNull($execution->getStartTime()); + $this->assertNull($execution->getEndTime()); + + $execution = $this->taskExecutionRepository->findByUuid($executions[2]->getUuid()); + $this->assertEquals(TaskStatus::COMPLETED, $execution->getStatus()); + $this->assertEquals(strrev('Test workload 3'), $execution->getResult()); + $this->assertGreaterThan(0, $execution->getDuration()); + $this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime()); $result = $this->taskExecutionRepository->findAll(2, 3); $this->assertCount(1, $result); @@ -86,21 +89,24 @@ public function testExecuteWithFail() ] ); - $this->assertEquals(TaskStatus::FAILED, $executions[0]->getStatus()); - $this->assertNull($executions[0]->getResult()); - $this->assertGreaterThan(0, $executions[0]->getDuration()); - $this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime()); - - $this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus()); - $this->assertNull($executions[1]->getResult()); - $this->assertNull($executions[1]->getDuration()); - $this->assertNull($executions[1]->getStartTime()); - $this->assertNull($executions[1]->getEndTime()); - - $this->assertEquals(TaskStatus::FAILED, $executions[2]->getStatus()); - $this->assertNull($executions[2]->getResult()); - $this->assertGreaterThan(0, $executions[2]->getDuration()); - $this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime()); + $execution = $this->taskExecutionRepository->findByUuid($executions[0]->getUuid()); + $this->assertEquals(TaskStatus::FAILED, $execution->getStatus()); + $this->assertNull($execution->getResult()); + $this->assertGreaterThan(0, $execution->getDuration()); + $this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime()); + + $execution = $this->taskExecutionRepository->findByUuid($executions[1]->getUuid()); + $this->assertEquals(TaskStatus::PLANNED, $execution->getStatus()); + $this->assertNull($execution->getResult()); + $this->assertNull($execution->getDuration()); + $this->assertNull($execution->getStartTime()); + $this->assertNull($execution->getEndTime()); + + $execution = $this->taskExecutionRepository->findByUuid($executions[2]->getUuid()); + $this->assertEquals(TaskStatus::FAILED, $execution->getStatus()); + $this->assertNull($execution->getResult()); + $this->assertGreaterThan(0, $execution->getDuration()); + $this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime()); $result = $this->taskExecutionRepository->findAll(2, 3); $this->assertCount(1, $result); diff --git a/tests/Functional/Command/ScheduleTaskCommandTest.php b/tests/Functional/Command/ScheduleTaskCommandTest.php index b7df0ea..b88696a 100644 --- a/tests/Functional/Command/ScheduleTaskCommandTest.php +++ b/tests/Functional/Command/ScheduleTaskCommandTest.php @@ -119,7 +119,7 @@ public function testExecuteWithExecutionDate() $this->assertCount(1, $executions); $this->assertEquals(TestHandler::class, $executions[0]->getHandlerClass()); - $this->assertEquals($date, $executions[0]->getScheduleTime()); + $this->assertEquals($date, $executions[0]->getScheduleTime(), '', 2); } /** diff --git a/tests/Unit/EventListener/TaskExecutionListenerTest.php b/tests/Unit/EventListener/TaskExecutionListenerTest.php new file mode 100644 index 0000000..7cbf1e4 --- /dev/null +++ b/tests/Unit/EventListener/TaskExecutionListenerTest.php @@ -0,0 +1,32 @@ +prophesize(EntityManagerInterface::class); + + $listener = new DoctrineTaskExecutionListener($entityManager->reveal()); + $listener->clearEntityManagerAfterTask($this->prophesize(TaskExecutionEvent::class)->reveal()); + + $entityManager->clear()->shouldBeCalled(); + } +}