Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f5b20bd

Browse files
committed
Add a the lock component with basic implementation
1 parent cbecfc3 commit f5b20bd

38 files changed

+2470
-0
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"symfony/inflector": "self.version",
5252
"symfony/intl": "self.version",
5353
"symfony/ldap": "self.version",
54+
"symfony/lock": "self.version",
5455
"symfony/monolog-bridge": "self.version",
5556
"symfony/options-resolver": "self.version",
5657
"symfony/process": "self.version",

src/Symfony/Component/Lock/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
phpunit.xml
3+
vendor/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* Base ExceptionInterface for the Lock Component.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
interface ExceptionInterface
20+
{
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* @author Jérémy Derussé <[email protected]>
16+
*/
17+
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
18+
{
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* LockAcquiringException is thrown when an issue happens during the acquisition of a lock.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
class LockAcquiringException extends \RuntimeException implements ExceptionInterface
20+
{
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* LockConflictedException is thrown when a lock is acquired by someone else.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
class LockConflictedException extends \RuntimeException implements ExceptionInterface
20+
{
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* LockReleasingException is thrown when an issue happens during the release of a lock.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
class LockReleasingException extends \RuntimeException implements ExceptionInterface
20+
{
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* LockStorageException is thrown when an issue happens during the manipulation of a lock in a store.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
class LockStorageException extends \RuntimeException implements ExceptionInterface
20+
{
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* NotSupportedException is thrown when a unsupported method is called.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
class NotSupportedException extends \LogicException implements ExceptionInterface
20+
{
21+
}

src/Symfony/Component/Lock/Key.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
/**
15+
* Key is a container for the state of the locks in stores.
16+
*
17+
* @author Jérémy Derussé <[email protected]>
18+
*/
19+
final class Key
20+
{
21+
private $resource;
22+
private $state = array();
23+
24+
/**
25+
* @param string $resource
26+
*/
27+
public function __construct($resource)
28+
{
29+
$this->resource = (string) $resource;
30+
}
31+
32+
public function __toString()
33+
{
34+
return $this->resource;
35+
}
36+
37+
/**
38+
* @param string $stateKey
39+
*
40+
* @return bool
41+
*/
42+
public function hasState($stateKey)
43+
{
44+
return isset($this->state[$stateKey]);
45+
}
46+
47+
/**
48+
* @param string $stateKey
49+
* @param mixed $state
50+
*/
51+
public function setState($stateKey, $state)
52+
{
53+
$this->state[$stateKey] = $state;
54+
}
55+
56+
/**
57+
* @param string $stateKey
58+
*/
59+
public function removeState($stateKey)
60+
{
61+
unset($this->state[$stateKey]);
62+
}
63+
64+
public function getState($stateKey)
65+
{
66+
return $this->state[$stateKey];
67+
}
68+
}

src/Symfony/Component/Lock/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2016-2017 Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

src/Symfony/Component/Lock/Lock.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
use Psr\Log\LoggerAwareTrait;
15+
use Psr\Log\NullLogger;
16+
use Symfony\Component\Lock\Exception\InvalidArgumentException;
17+
use Symfony\Component\Lock\Exception\LockAcquiringException;
18+
use Symfony\Component\Lock\Exception\LockConflictedException;
19+
use Symfony\Component\Lock\Exception\LockReleasingException;
20+
21+
/**
22+
* Lock is the default implementation of the LockInterface.
23+
*
24+
* @author Jérémy Derussé <[email protected]>
25+
*/
26+
final class Lock implements LockInterface
27+
{
28+
use LoggerAwareTrait;
29+
30+
private $store;
31+
private $key;
32+
private $ttl;
33+
34+
/**
35+
* @param Key $key
36+
* @param StoreInterface $store
37+
* @param float|null $ttl
38+
*/
39+
public function __construct(Key $key, StoreInterface $store, $ttl = null)
40+
{
41+
$this->store = $store;
42+
$this->key = $key;
43+
$this->ttl = $ttl;
44+
45+
$this->logger = new NullLogger();
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function acquire($blocking = false)
52+
{
53+
try {
54+
if (!$blocking) {
55+
$this->store->save($this->key);
56+
} else {
57+
$this->store->waitAndSave($this->key);
58+
}
59+
60+
$this->logger->info('Lock successfully acquired for "{resource}"', array('resource' => $this->key));
61+
62+
if ($this->ttl) {
63+
$this->refresh();
64+
}
65+
} catch (LockConflictedException $e) {
66+
$this->logger->warning('Failed to lock the "{resource}". Someone else already acquired the lock', array('resource' => $this->key));
67+
throw $e;
68+
} catch (\Exception $e) {
69+
$this->logger->warning('Failed to lock the "{resource}"', array('resource' => $this->key, 'exception' => $e));
70+
throw new LockAcquiringException('', 0, $e);
71+
}
72+
}
73+
74+
/**
75+
* {@inheritdoc}
76+
*/
77+
public function refresh()
78+
{
79+
if (!$this->ttl) {
80+
throw new InvalidArgumentException('You have to define an expiration duration');
81+
}
82+
83+
try {
84+
$this->store->putOffExpiration($this->key, $this->ttl);
85+
$this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds', array('resource' => $this->key, 'ttl' => $this->ttl));
86+
} catch (LockConflictedException $e) {
87+
$this->logger->warning('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock', array('resource' => $this->key));
88+
throw $e;
89+
} catch (\Exception $e) {
90+
$this->logger->warning('Failed to define an expiration for the "{resource}" lock', array('resource' => $this->key, 'exception' => $e));
91+
throw new LockAcquiringException('', 0, $e);
92+
}
93+
}
94+
95+
/**
96+
* {@inheritdoc}
97+
*/
98+
public function isAcquired()
99+
{
100+
return $this->store->exists($this->key);
101+
}
102+
103+
/**
104+
* {@inheritdoc}
105+
*/
106+
public function release()
107+
{
108+
$this->store->delete($this->key);
109+
110+
if ($this->store->exists($this->key)) {
111+
$this->logger->warning('Failed to release the "{resource}" lock', array('resource' => $this->key));
112+
throw new LockReleasingException();
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)