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