mirror of
https://github.com/friendica/friendica
synced 2025-04-27 03:10:12 +00:00
Lock now can use the memcache as well
This commit is contained in:
parent
d2cb87a200
commit
bca5776e9c
2 changed files with 104 additions and 12 deletions
|
@ -8,6 +8,8 @@ namespace Friendica\Util;
|
|||
*
|
||||
*/
|
||||
|
||||
use Friendica\Core\Config;
|
||||
use Memcache;
|
||||
use dba;
|
||||
use dbm;
|
||||
|
||||
|
@ -15,6 +17,31 @@ use dbm;
|
|||
* @brief This class contain Functions for preventing parallel execution of functions
|
||||
*/
|
||||
class Lock {
|
||||
/**
|
||||
* @brief Check for memcache and open a connection if configured
|
||||
*
|
||||
* @return object|boolean The memcache object - or "false" if not successful
|
||||
*/
|
||||
public static function memcache() {
|
||||
if (!function_exists('memcache_connect')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Config::get('system', 'memcache')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$memcache_host = Config::get('system', 'memcache_host', '127.0.0.1');
|
||||
$memcache_port = Config::get('system', 'memcache_port', 11211);
|
||||
|
||||
$memcache = new Memcache;
|
||||
|
||||
if (!$memcache->connect($memcache_host, $memcache_port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for a given name
|
||||
|
@ -33,6 +60,33 @@ class Lock {
|
|||
$got_lock = false;
|
||||
$start = time();
|
||||
|
||||
$memcache = self::memcache();
|
||||
if (is_object($memcache)) {
|
||||
$cachekey = get_app()->get_hostname().";lock:".$fn_name;
|
||||
|
||||
do {
|
||||
$lock = $memcache->get($cachekey);
|
||||
|
||||
if (!is_bool($lock)) {
|
||||
$pid = (int)$lock;
|
||||
|
||||
// When the process id isn't used anymore, we can safely claim the lock for us.
|
||||
// Or we do want to lock something that was already locked by us.
|
||||
if (!posix_kill($pid, 0) OR ($pid == getmypid())) {
|
||||
$lock = false;
|
||||
}
|
||||
}
|
||||
if (is_bool($lock)) {
|
||||
$memcache->set($cachekey, getmypid(), MEMCACHE_COMPRESSED, 300);
|
||||
$got_lock = true;
|
||||
}
|
||||
if (!$got_lock) {
|
||||
sleep($wait_sec);
|
||||
}
|
||||
} while (!$got_lock AND ((time() - $start) < $timeout));
|
||||
|
||||
return $got_lock;
|
||||
}
|
||||
do {
|
||||
dba::lock('locks');
|
||||
$lock = dba::select('locks', array('locked', 'pid'), array('name' => $fn_name), array('limit' => 1));
|
||||
|
@ -73,7 +127,34 @@ class Lock {
|
|||
* @param string $fn_name Name of the lock
|
||||
*/
|
||||
public static function remove($fn_name) {
|
||||
$memcache = self::memcache();
|
||||
if (is_object($memcache)) {
|
||||
$cachekey = get_app()->get_hostname().";lock:".$fn_name;
|
||||
$lock = $memcache->get($cachekey);
|
||||
|
||||
if (!is_bool($lock)) {
|
||||
if ((int)$lock == getmypid()) {
|
||||
$memcache->delete($cachekey);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
dba::update('locks', array('locked' => false, 'pid' => 0), array('name' => $fn_name, 'pid' => getmypid()));
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes all lock that were set by us
|
||||
*/
|
||||
public static function removeAll() {
|
||||
$memcache = self::memcache();
|
||||
if (is_object($memcache)) {
|
||||
// We cannot delete all cache entries, but this doesn't matter with memcache
|
||||
return;
|
||||
}
|
||||
|
||||
dba::update('locks', array('locked' => false, 'pid' => 0), array('pid' => getmypid()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue