feature #23724 [Lock] Deprecate Filesystem/LockHandler (jderusse)

This PR was merged into the 3.4 branch.

Discussion
----------

[Lock] Deprecate Filesystem/LockHandler

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/8243

This PR deprecate the `Filesystem\LockHandler` in favor of `Lock\SemaphoreStore` and `Lock\FlockStore`.

Commits
-------

67ecc71364 Deprecate Filesystem/LockHandler
This commit is contained in:
Fabien Potencier 2017-08-01 07:25:57 +02:00
commit 57a86fb705
9 changed files with 77 additions and 22 deletions

View File

@ -11,6 +11,13 @@ Debug
* Support for stacked errors in the `ErrorHandler` is deprecated and will be removed in Symfony 4.0.
Filesystem
----------
* The `Symfony\Component\Filesystem\LockHandler` class has been deprecated,
use the `Symfony\Component\Lock\Store\FlockStore` class
or the `Symfony\Component\Lock\Store\FlockStore\SemaphoreStore` class directly instead.
Finder
------

View File

@ -147,6 +147,13 @@ ExpressionLanguage
class has been removed. You should use the `CacheItemPoolInterface` interface
instead.
Filesystem
----------
* The `Symfony\Component\Filesystem\LockHandler` has been removed,
use the `Symfony\Component\Lock\Store\FlockStore` class
or the `Symfony\Component\Lock\Store\FlockStore\SemaphoreStore` class directly instead.
Finder
------

View File

@ -13,7 +13,10 @@ namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Filesystem\LockHandler;
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Lock;
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;
/**
* Basic lock feature for commands.
@ -22,7 +25,8 @@ use Symfony\Component\Filesystem\LockHandler;
*/
trait LockableTrait
{
private $lockHandler;
/** @var Lock */
private $lock;
/**
* Locks a command.
@ -31,18 +35,23 @@ trait LockableTrait
*/
private function lock($name = null, $blocking = false)
{
if (!class_exists(LockHandler::class)) {
throw new RuntimeException('To enable the locking feature you must install the symfony/filesystem component.');
if (!class_exists(SemaphoreStore::class)) {
throw new RuntimeException('To enable the locking feature you must install the symfony/lock component.');
}
if (null !== $this->lockHandler) {
if (null !== $this->lock) {
throw new LogicException('A lock is already in place.');
}
$this->lockHandler = new LockHandler($name ?: $this->getName());
if (SemaphoreStore::isSupported($blocking)) {
$store = new SemaphoreStore();
} else {
$store = new FlockStore(sys_get_temp_dir());
}
if (!$this->lockHandler->lock($blocking)) {
$this->lockHandler = null;
$this->lock = (new Factory($store))->createLock($name ?: $this->getName());
if (!$this->lock->acquire($blocking)) {
$this->lock = null;
return false;
}
@ -55,9 +64,9 @@ trait LockableTrait
*/
private function release()
{
if ($this->lockHandler) {
$this->lockHandler->release();
$this->lockHandler = null;
if ($this->lock) {
$this->lock->release();
$this->lock = null;
}
}
}

View File

@ -13,7 +13,9 @@ namespace Symfony\Component\Console\Tests\Command;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Filesystem\LockHandler;
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;
class LockableTraitTest extends TestCase
{
@ -39,8 +41,14 @@ class LockableTraitTest extends TestCase
{
$command = new \FooLockCommand();
$lock = new LockHandler($command->getName());
$lock->lock();
if (SemaphoreStore::isSupported(false)) {
$store = new SemaphoreStore();
} else {
$store = new FlockStore(sys_get_temp_dir());
}
$lock = (new Factory($store))->createLock($command->getName());
$lock->acquire();
$tester = new CommandTester($command);
$this->assertSame(1, $tester->execute(array()));

View File

@ -25,13 +25,13 @@
"symfony/http-kernel": "~2.8|~3.0|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/dependency-injection": "~3.3|~4.0",
"symfony/filesystem": "~2.8|~3.0|~4.0",
"symfony/lock": "~3.4|~4.0",
"symfony/process": "~3.3|~4.0",
"psr/log": "~1.0"
},
"suggest": {
"symfony/event-dispatcher": "",
"symfony/filesystem": "",
"symfony/lock": "",
"symfony/process": "",
"psr/log": "For using the console logger"
},

View File

@ -11,7 +11,11 @@
namespace Symfony\Component\Filesystem;
@trigger_error(sprintf('The %s class is deprecated since version 3.4 and will be removed in 4.0. Use %s or %s instead.', LockHandler::class, SemaphoreStore::class, FlockStore::class), E_USER_DEPRECATED);
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;
/**
* LockHandler class provides a simple abstraction to lock anything by means of
@ -25,6 +29,8 @@ use Symfony\Component\Filesystem\Exception\IOException;
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Romain Neutron <imprec@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*
* @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\Lock\Store\SemaphoreStore or Symfony\Component\Lock\Store\FlockStore instead.
*/
class LockHandler
{

View File

@ -16,6 +16,9 @@ use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\LockHandler;
/**
* @group legacy
*/
class LockHandlerTest extends TestCase
{
/**

View File

@ -24,9 +24,24 @@ use Symfony\Component\Lock\StoreInterface;
*/
class SemaphoreStore implements StoreInterface
{
public static function isSupported()
/**
* Returns whether or not the store is supported.
*
* @param bool|null $blocking When not null, checked again the blocking mode.
*
* @return bool
*/
public static function isSupported($blocking = null)
{
return extension_loaded('sysvsem');
if (!extension_loaded('sysvsem')) {
return false;
}
if ($blocking === false && \PHP_VERSION_ID < 50601) {
return false;
}
return true;
}
public function __construct()

View File

@ -35,7 +35,7 @@ trait BlockingStoreTestTrait
public function testBlockingLocks()
{
// Amount a microsecond used to order async actions
$clockDelay = 50000;
$clockDelay = 200000;
if (\PHP_VERSION_ID < 50600 || defined('HHVM_VERSION_ID')) {
$this->markTestSkipped('The PHP engine does not keep resource in child forks');
@ -49,7 +49,7 @@ trait BlockingStoreTestTrait
if ($childPID1 = pcntl_fork()) {
// give time to fork to start
usleep(2 * $clockDelay);
usleep(1 * $clockDelay);
try {
// This call should failed given the lock should already by acquired by the child #1
@ -69,8 +69,8 @@ trait BlockingStoreTestTrait
} else {
try {
$store->save($key);
// Wait 3 ClockDelay to let parent process to finish
usleep(3 * $clockDelay);
// Wait 2 ClockDelay to let parent process to finish
usleep(2 * $clockDelay);
$store->delete($key);
exit(0);
} catch (\Exception $e) {