Skip to content

Commit 7c037c4

Browse files
added lock to config
1 parent 3f1f0dd commit 7c037c4

File tree

12 files changed

+210
-14
lines changed

12 files changed

+210
-14
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
],
1212
"require": {
1313
"php": "~5.5 || ~7.0",
14-
"php-task/php-task": "^1.0",
14+
"php-task/php-task": "dev-feature/lock",
1515
"symfony/http-kernel": "^2.6 || ^3.0",
1616
"symfony/dependency-injection": "^2.6 || ^3.0",
17+
"symfony/expression-language": "^2.6 || ^3.0",
1718
"symfony/config": "^2.6 || ^3.0",
1819
"symfony/console": "^2.6 || ^3.0",
1920
"doctrine/orm": "^2.5"

src/DependencyInjection/Configuration.php

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@
1919
*/
2020
class Configuration implements ConfigurationInterface
2121
{
22+
/**
23+
* @var string[]
24+
*/
25+
private $lockingStorageAliases = [];
26+
27+
/**
28+
* @param \string[] $lockingStorageAliases
29+
*/
30+
public function __construct(array $lockingStorageAliases)
31+
{
32+
$this->lockingStorageAliases = $lockingStorageAliases;
33+
}
34+
2235
/**
2336
* {@inheritdoc}
2437
*/
@@ -43,14 +56,45 @@ public function getConfigTreeBuilder()
4356
->arrayNode('run')
4457
->addDefaultsIfNotSet()
4558
->children()
46-
->enumNode('mode')
47-
->values(['off', 'listener'])
48-
->defaultValue('off')
59+
->enumNode('mode')->values(['off', 'listener'])->defaultValue('off')->end()
60+
->end()
61+
->end()
62+
->arrayNode('locking')
63+
->canBeEnabled()
64+
->addDefaultsIfNotSet()
65+
->children()
66+
->enumNode('storage')
67+
->values(array_keys($this->lockingStorageAliases))
68+
->defaultValue('file')
69+
->end()
70+
->arrayNode('storages')
71+
->addDefaultsIfNotSet()
72+
->children()
73+
->arrayNode('file')
74+
->addDefaultsIfNotSet()
75+
->children()
76+
->scalarNode('directory')->defaultValue(sys_get_temp_dir() . '/task')->end()
77+
->end()
78+
->end()
79+
->end()
4980
->end()
81+
->enumNode('mode')->values(['off', 'listener'])->defaultValue('off')->end()
5082
->end()
5183
->end()
5284
->end();
5385

5486
return $treeBuilder;
5587
}
88+
89+
/**
90+
* Returns id for given storage-alias.
91+
*
92+
* @param string $alias
93+
*
94+
* @return string
95+
*/
96+
public function getLockingStorageId($alias)
97+
{
98+
return $this->lockingStorageAliases[$alias];
99+
}
56100
}

src/DependencyInjection/TaskExtension.php

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Task\TaskBundle\DependencyInjection;
1313

1414
use Symfony\Component\Config\FileLocator;
15+
use Symfony\Component\Config\Loader\LoaderInterface;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\ContainerInterface;
1718
use Symfony\Component\DependencyInjection\Definition;
@@ -31,20 +32,28 @@ class TaskExtension extends Extension
3132
*/
3233
public function load(array $configs, ContainerBuilder $container)
3334
{
34-
$configuration = new Configuration();
35+
$configuration = $this->getConfiguration($configs, $container);
3536
$config = $this->processConfiguration($configuration, $configs);
3637

38+
$container->setAlias('task.lock.storage', $configuration->getLockingStorageId($config['locking']['storage']));
39+
40+
foreach (array_keys($config['locking']['storages']) as $key) {
41+
$container->setParameter('task.lock.storages.' . $key, $config['locking']['storages'][$key]);
42+
}
43+
3744
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
3845
$loader->load(sprintf('storage/%s.xml', $config['storage']));
3946
$loader->load('task_event_listener.xml');
4047
$loader->load('scheduler.xml');
4148
$loader->load('command.xml');
4249

50+
$loader->load('locking/services.xml');
4351
if ($config['run']['mode'] === 'listener') {
4452
$loader->load('listener.xml');
4553
}
4654

4755
$this->loadDoctrineAdapter($config['adapters']['doctrine'], $container);
56+
$this->loadLockingComponent($config['locking'], $loader);
4857
}
4958

5059
/**
@@ -67,4 +76,51 @@ private function loadDoctrineAdapter(array $config, ContainerBuilder $container)
6776
$container->setDefinition('task.adapter.doctrine.execution_listener', $definition);
6877
}
6978
}
79+
80+
/**
81+
* Load services for locking component.
82+
*
83+
* @param array $config
84+
* @param LoaderInterface $loader
85+
*/
86+
private function loadLockingComponent(array $config, LoaderInterface $loader)
87+
{
88+
if (!$config['enabled']) {
89+
return $loader->load('locking/null.xml');
90+
}
91+
92+
$loader->load('locking/services.xml');
93+
}
94+
95+
/**
96+
* Find storage aliases and related ids.
97+
*
98+
* @param ContainerBuilder $container
99+
*
100+
* @return array
101+
*/
102+
private function getLockingStorageAliases(ContainerBuilder $container)
103+
{
104+
$taggedServices = $container->findTaggedServiceIds('task.lock.storage');
105+
106+
$result = [];
107+
foreach ($taggedServices as $id => $tags) {
108+
foreach ($tags as $tag) {
109+
$result[$tag['alias']] = $id;
110+
}
111+
}
112+
113+
return $result;
114+
}
115+
116+
/**
117+
* {@inheritdoc}
118+
*/
119+
public function getConfiguration(array $config, ContainerBuilder $container)
120+
{
121+
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
122+
$loader->load('locking/storages.xml');
123+
124+
return new Configuration($this->getLockingStorageAliases($container));
125+
}
70126
}

src/Entity/TaskExecutionRepository.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ public function findNextScheduled(\DateTime $dateTime = null)
140140
->setMaxResults(1)
141141
->getQuery();
142142

143-
return $query->getResult();
143+
try {
144+
return $query->getSingleResult();
145+
} catch (NoResultException $exception) {
146+
return null;
147+
}
144148
}
145149
}

src/Locking/NullLock.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\Locking;
13+
14+
use Task\Execution\TaskExecutionInterface;
15+
use Task\Lock\LockInterface;
16+
17+
/**
18+
* Implements LockInterface which does nothing.
19+
*/
20+
class NullLock implements LockInterface
21+
{
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function acquire(TaskExecutionInterface $execution)
26+
{
27+
return true;
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function refresh(TaskExecutionInterface $execution)
34+
{
35+
return true;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function release(TaskExecutionInterface $execution)
42+
{
43+
return true;
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function isAcquired(TaskExecutionInterface $execution)
50+
{
51+
return false;
52+
}
53+
}

src/Resources/config/locking/null.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5+
<services>
6+
<service id="task.lock" class="Task\TaskBundle\Locking\NullLock"/>
7+
</services>
8+
</container>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5+
<services>
6+
<service id="task.lock.strategy" class="Task\Lock\Strategy\HandlerClassStrategy"/>
7+
8+
<service id="task.lock" class="Task\Lock\Lock">
9+
<argument type="service" id="task.lock.strategy"/>
10+
<argument type="service" id="task.lock.storage"/>
11+
</service>
12+
</services>
13+
</container>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5+
<services>
6+
<service id="task.lock.storage.file" class="Task\Lock\Storage\FileLock">
7+
<argument type="expression">parameter('task.lock.storages.file')['directory']</argument>
8+
9+
<tag name="task.lock.storage" alias="file"/>
10+
</service>
11+
</services>
12+
</container>

src/Resources/config/scheduler.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<service id="task.runner" class="Task\Runner\TaskRunner">
2020
<argument type="service" id="task.storage.task_execution"/>
2121
<argument type="service" id="task.handler.factory"/>
22+
<argument type="service" id="task.lock"/>
2223
<argument type="service" id="event_dispatcher"/>
2324
</service>
2425
</services>

tests/Functional/Entity/TaskExecutionRepositoryTest.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,8 @@ public function testFindScheduledPast()
156156

157157
$execution = $this->save($task, new \DateTime('-1 hour'));
158158

159-
$result = $this->taskExecutionRepository->findScheduled();
160-
161-
$this->assertCount(1, $result);
162-
$this->assertEquals($execution->getUuid(), $result[0]->getUuid());
159+
$result = $this->taskExecutionRepository->findNextScheduled();
160+
$this->assertEquals($execution->getUuid(), $result->getUuid());
163161
}
164162

165163
public function testFindScheduledFuture()
@@ -169,7 +167,7 @@ public function testFindScheduledFuture()
169167

170168
$this->save($task, new \DateTime('+1 hour'));
171169

172-
$this->assertEmpty($this->taskExecutionRepository->findScheduled());
170+
$this->assertNull($this->taskExecutionRepository->findNextScheduled());
173171
}
174172

175173
/**

tests/Functional/Handler/TaskHandlerFactoryTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Task\TaskBundle\Tests\Functional\Handler;
1313

1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
15-
use Task\Handler\TaskHandlerNotExistsException;
1615
use Task\TaskBundle\Handler\TaskHandlerFactory;
1716
use Task\TaskBundle\Tests\Functional\TestHandler;
1817

@@ -39,10 +38,11 @@ public function testCreate()
3938
$this->assertInstanceOf(TestHandler::class, $this->taskHandlerFactory->create(TestHandler::class));
4039
}
4140

41+
/**
42+
* @expectedException \Task\Handler\TaskHandlerNotExistsException
43+
*/
4244
public function testCreateNotExists()
4345
{
44-
$this->setExpectedException(TaskHandlerNotExistsException::class);
45-
4646
$this->taskHandlerFactory->create(\stdClass::class);
4747
}
4848
}

tests/app/config/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
parameters:
22
kernel.secret: 12345
3+
4+
task:
5+
locking:
6+
storages:
7+
file:
8+
directory: %kernel.cache_dir%/locks

0 commit comments

Comments
 (0)