Skip to content

Commit 481637c

Browse files
wachterjohannesdanrot
authored andcommitted
Clear entity-manager after each task to ensure clean environment (#34)
* added new function to task-execution repository * added task-execution listener to clear entity-manager * renamed task-execution listener * improved test-stabability * reverted dependency changes
1 parent a45cae8 commit 481637c

File tree

8 files changed

+170
-37
lines changed

8 files changed

+170
-37
lines changed

src/DependencyInjection/Configuration.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ public function getConfigTreeBuilder()
2929
$treeBuilder->root('task')
3030
->children()
3131
->enumNode('storage')->values(['array', 'doctrine'])->defaultValue('doctrine')->end()
32+
->arrayNode('adapters')
33+
->addDefaultsIfNotSet()
34+
->children()
35+
->arrayNode('doctrine')
36+
->addDefaultsIfNotSet()
37+
->children()
38+
->booleanNode('clear')->defaultTrue()->end()
39+
->end()
40+
->end()
41+
->end()
42+
->end()
3243
->arrayNode('run')
3344
->addDefaultsIfNotSet()
3445
->children()

src/DependencyInjection/TaskExtension.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@
1313

1414
use Symfony\Component\Config\FileLocator;
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\ContainerInterface;
17+
use Symfony\Component\DependencyInjection\Definition;
1618
use Symfony\Component\DependencyInjection\Loader;
1719
use Symfony\Component\DependencyInjection\Reference;
1820
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
21+
use Task\Event\Events;
22+
use Task\TaskBundle\EventListener\DoctrineTaskExecutionListener;
1923

2024
/**
2125
* Container extension for php-task library.
@@ -40,12 +44,27 @@ public function load(array $configs, ContainerBuilder $container)
4044
$loader->load('listener.xml');
4145
}
4246

43-
if ('doctrine' === $config['storage']) {
44-
// FIXME move to compiler pass
45-
$container->getDefinition('task.command.schedule_task')
46-
->addArgument(new Reference('doctrine.orm.entity_manager'));
47-
$container->getDefinition('task.command.run')
48-
->addArgument(new Reference('doctrine.orm.entity_manager'));
47+
$this->loadDoctrineAdapter($config['adapters']['doctrine'], $container);
48+
}
49+
50+
/**
51+
* Load doctrine adapter.
52+
*
53+
* @param array $config
54+
* @param ContainerBuilder $container
55+
*/
56+
private function loadDoctrineAdapter(array $config, ContainerBuilder $container)
57+
{
58+
if ($config['clear']) {
59+
$definition = new Definition(
60+
DoctrineTaskExecutionListener::class,
61+
[new Reference('doctrine.orm.entity_manager', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
62+
);
63+
$definition->addTag(
64+
'kernel.event_listener',
65+
['event' => Events::TASK_AFTER, 'method' => 'clearEntityManagerAfterTask']
66+
);
67+
$container->setDefinition('task.adapter.doctrine.execution_listener', $definition);
4968
}
5069
}
5170
}

src/Entity/TaskExecutionRepository.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,22 @@ public function findPending(TaskInterface $task)
8989
}
9090
}
9191

92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function findByUuid($uuid)
96+
{
97+
try {
98+
return $this->createQueryBuilder('e')
99+
->where('e.uuid = :uuid')
100+
->setParameter('uuid', $uuid)
101+
->getQuery()
102+
->getSingleResult();
103+
} catch (NoResultException $e) {
104+
return;
105+
}
106+
}
107+
92108
/**
93109
* {@inheritdoc}
94110
*/
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of php-task library.
5+
*
6+
* (c) php-task
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*/
11+
12+
namespace Task\TaskBundle\EventListener;
13+
14+
use Doctrine\ORM\EntityManagerInterface;
15+
use Task\Event\TaskExecutionEvent;
16+
17+
/**
18+
* Listens on task-execution events.
19+
*/
20+
class DoctrineTaskExecutionListener
21+
{
22+
/**
23+
* @var EntityManagerInterface
24+
*/
25+
private $entityManager;
26+
27+
/**
28+
* @param EntityManagerInterface $entityManager
29+
*/
30+
public function __construct(EntityManagerInterface $entityManager = null)
31+
{
32+
$this->entityManager = $entityManager;
33+
}
34+
35+
/**
36+
* This method clears the entity-manager after each task to ensure clean state before next task.
37+
*
38+
* @param TaskExecutionEvent $event
39+
*/
40+
public function clearEntityManagerAfterTask(TaskExecutionEvent $event)
41+
{
42+
if (!$this->entityManager) {
43+
return;
44+
}
45+
46+
$this->entityManager->clear();
47+
}
48+
}

src/Resources/config/task_event_listener.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<parameter key="task.events.create" type="constant">Task\Event\Events::TASK_CREATE</parameter>
88
<parameter key="task.events.create_execution" type="constant">Task\Event\Events::TASK_EXECUTION_CREATE</parameter>
99
<parameter key="task.events.before" type="constant">Task\Event\Events::TASK_BEFORE</parameter>
10+
<parameter key="task.events.after" type="constant">Task\Event\Events::TASK_AFTER</parameter>
1011
<parameter key="task.events.finished" type="constant">Task\Event\Events::TASK_FINISHED</parameter>
1112
<parameter key="task.events.passed" type="constant">Task\Event\Events::TASK_PASSED</parameter>
1213
<parameter key="task.events.failed" type="constant">Task\Event\Events::TASK_FAILED</parameter>

tests/Functional/Command/RunCommandTest.php

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,24 @@ public function testExecute()
4242
]
4343
);
4444

45-
$this->assertEquals(TaskStatus::COMPLETED, $executions[0]->getStatus());
46-
$this->assertEquals(strrev('Test workload 1'), $executions[0]->getResult());
47-
$this->assertGreaterThan(0, $executions[0]->getDuration());
48-
$this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime());
49-
50-
$this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus());
51-
$this->assertNull($executions[1]->getResult());
52-
$this->assertNull($executions[1]->getDuration());
53-
$this->assertNull($executions[1]->getStartTime());
54-
$this->assertNull($executions[1]->getEndTime());
55-
56-
$this->assertEquals(TaskStatus::COMPLETED, $executions[2]->getStatus());
57-
$this->assertEquals(strrev('Test workload 3'), $executions[2]->getResult());
58-
$this->assertGreaterThan(0, $executions[2]->getDuration());
59-
$this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime());
45+
$execution = $this->taskExecutionRepository->findByUuid($executions[0]->getUuid());
46+
$this->assertEquals(TaskStatus::COMPLETED, $execution->getStatus());
47+
$this->assertEquals(strrev('Test workload 1'), $execution->getResult());
48+
$this->assertGreaterThan(0, $execution->getDuration());
49+
$this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime());
50+
51+
$execution = $this->taskExecutionRepository->findByUuid($executions[1]->getUuid());
52+
$this->assertEquals(TaskStatus::PLANNED, $execution->getStatus());
53+
$this->assertNull($execution->getResult());
54+
$this->assertNull($execution->getDuration());
55+
$this->assertNull($execution->getStartTime());
56+
$this->assertNull($execution->getEndTime());
57+
58+
$execution = $this->taskExecutionRepository->findByUuid($executions[2]->getUuid());
59+
$this->assertEquals(TaskStatus::COMPLETED, $execution->getStatus());
60+
$this->assertEquals(strrev('Test workload 3'), $execution->getResult());
61+
$this->assertGreaterThan(0, $execution->getDuration());
62+
$this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime());
6063

6164
$result = $this->taskExecutionRepository->findAll(2, 3);
6265
$this->assertCount(1, $result);
@@ -86,21 +89,24 @@ public function testExecuteWithFail()
8689
]
8790
);
8891

89-
$this->assertEquals(TaskStatus::FAILED, $executions[0]->getStatus());
90-
$this->assertNull($executions[0]->getResult());
91-
$this->assertGreaterThan(0, $executions[0]->getDuration());
92-
$this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime());
93-
94-
$this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus());
95-
$this->assertNull($executions[1]->getResult());
96-
$this->assertNull($executions[1]->getDuration());
97-
$this->assertNull($executions[1]->getStartTime());
98-
$this->assertNull($executions[1]->getEndTime());
99-
100-
$this->assertEquals(TaskStatus::FAILED, $executions[2]->getStatus());
101-
$this->assertNull($executions[2]->getResult());
102-
$this->assertGreaterThan(0, $executions[2]->getDuration());
103-
$this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime());
92+
$execution = $this->taskExecutionRepository->findByUuid($executions[0]->getUuid());
93+
$this->assertEquals(TaskStatus::FAILED, $execution->getStatus());
94+
$this->assertNull($execution->getResult());
95+
$this->assertGreaterThan(0, $execution->getDuration());
96+
$this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime());
97+
98+
$execution = $this->taskExecutionRepository->findByUuid($executions[1]->getUuid());
99+
$this->assertEquals(TaskStatus::PLANNED, $execution->getStatus());
100+
$this->assertNull($execution->getResult());
101+
$this->assertNull($execution->getDuration());
102+
$this->assertNull($execution->getStartTime());
103+
$this->assertNull($execution->getEndTime());
104+
105+
$execution = $this->taskExecutionRepository->findByUuid($executions[2]->getUuid());
106+
$this->assertEquals(TaskStatus::FAILED, $execution->getStatus());
107+
$this->assertNull($execution->getResult());
108+
$this->assertGreaterThan(0, $execution->getDuration());
109+
$this->assertGreaterThanOrEqual($execution->getStartTime(), $execution->getEndTime());
104110

105111
$result = $this->taskExecutionRepository->findAll(2, 3);
106112
$this->assertCount(1, $result);

tests/Functional/Command/ScheduleTaskCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public function testExecuteWithExecutionDate()
119119
$this->assertCount(1, $executions);
120120

121121
$this->assertEquals(TestHandler::class, $executions[0]->getHandlerClass());
122-
$this->assertEquals($date, $executions[0]->getScheduleTime());
122+
$this->assertEquals($date, $executions[0]->getScheduleTime(), '', 2);
123123
}
124124

125125
/**
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of php-task library.
5+
*
6+
* (c) php-task
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*/
11+
12+
namespace Task\TaskBundle\Tests\Unit\EventListener;
13+
14+
use Doctrine\ORM\EntityManagerInterface;
15+
use Task\Event\TaskExecutionEvent;
16+
use Task\TaskBundle\EventListener\DoctrineTaskExecutionListener;
17+
18+
/**
19+
* Tests for class TaskExecutionListener.
20+
*/
21+
class TaskExecutionListenerTest extends \PHPUnit_Framework_TestCase
22+
{
23+
public function testClearEntityManagerAfterTask()
24+
{
25+
$entityManager = $this->prophesize(EntityManagerInterface::class);
26+
27+
$listener = new DoctrineTaskExecutionListener($entityManager->reveal());
28+
$listener->clearEntityManagerAfterTask($this->prophesize(TaskExecutionEvent::class)->reveal());
29+
30+
$entityManager->clear()->shouldBeCalled();
31+
}
32+
}

0 commit comments

Comments
 (0)