mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-18 09:52:17 +09:00
Add Storage::getLock() for exclusive access to a named lock
여러 프로세스를 동시에 실행할 경우 1개만 작동하도록 lock을 관리하는 기능을 코어 프레임워크에서 제공하도록 한다. 두 개 이상의 프로세스에서 동일한 이름의 lock을 요청할 경우 먼저 요청한 프로세스는 true, 나머지 프로세스들은 false를 받게 된다. lock을 갖고 있던 프로세스가 종료되면 다시 요청할 수 있다. 예를 들어 크론탭에서 1분마다 실행하는 CLI 스크립트가 있는데 간혹 1분 이상 소요된다면 2개가 동시에 실행될 수도 있다. 이 때 lock을 받지 못한 쪽을 종료하면 동시 실행을 방지할 수 있다.
This commit is contained in:
parent
f278ae5e75
commit
4533dacd4b
1 changed files with 59 additions and 0 deletions
|
|
@ -22,6 +22,11 @@ class Storage
|
|||
*/
|
||||
protected static $_opcache;
|
||||
|
||||
/**
|
||||
* Cache locks here.
|
||||
*/
|
||||
protected static $_locks = array();
|
||||
|
||||
/**
|
||||
* Check if a path really exists.
|
||||
*
|
||||
|
|
@ -858,4 +863,58 @@ class Storage
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an exclusive lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function getLock($name)
|
||||
{
|
||||
$name = str_replace('.', '%2E', rawurlencode($name));
|
||||
if (isset(self::$_locks[$name]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$lockdir = \RX_BASEDIR . 'files/locks';
|
||||
if (!self::isDirectory($lockdir) && !self::createDirectory($lockdir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self::$_locks[$name] = @fopen($lockdir . '/' . $name . '.lock', 'w');
|
||||
if (!self::$_locks[$name])
|
||||
{
|
||||
unset(self::$_locks[$name]);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = @flock(self::$_locks[$name], \LOCK_EX | \LOCK_NB);
|
||||
if (!$result)
|
||||
{
|
||||
@fclose(self::$_locks[$name]);
|
||||
unset(self::$_locks[$name]);
|
||||
return false;
|
||||
}
|
||||
|
||||
register_shutdown_function('\\Rhymix\\Framework\\Storage::clearLocks');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all locks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clearLocks()
|
||||
{
|
||||
foreach (self::$_locks as $name => $lock)
|
||||
{
|
||||
@flock($lock, \LOCK_UN);
|
||||
@fclose($lock);
|
||||
@unlink(\RX_BASEDIR . 'files/locks/' . $name . '.lock');
|
||||
unset(self::$_locks[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue