Lock now can use the memcache as well
This commit is contained in:
parent
d2cb87a200
commit
bca5776e9c
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
use Friendica\Core\Config;
|
use Friendica\Core\Config;
|
||||||
|
use Friendica\Util\Lock;
|
||||||
|
|
||||||
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
|
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
|
||||||
$directory = dirname($_SERVER["argv"][0]);
|
$directory = dirname($_SERVER["argv"][0]);
|
||||||
|
@ -19,16 +20,12 @@ require_once("boot.php");
|
||||||
function poller_run($argv, $argc){
|
function poller_run($argv, $argc){
|
||||||
global $a, $db;
|
global $a, $db;
|
||||||
|
|
||||||
if (is_null($a)) {
|
$a = new App(dirname(__DIR__));
|
||||||
$a = new App(dirname(__DIR__));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_null($db)) {
|
@include(".htconfig.php");
|
||||||
@include(".htconfig.php");
|
require_once("include/dba.php");
|
||||||
require_once("include/dba.php");
|
$db = new dba($db_host, $db_user, $db_pass, $db_data);
|
||||||
$db = new dba($db_host, $db_user, $db_pass, $db_data);
|
unset($db_host, $db_user, $db_pass, $db_data);
|
||||||
unset($db_host, $db_user, $db_pass, $db_data);
|
|
||||||
};
|
|
||||||
|
|
||||||
Config::load();
|
Config::load();
|
||||||
|
|
||||||
|
@ -41,6 +38,10 @@ function poller_run($argv, $argc){
|
||||||
|
|
||||||
load_hooks();
|
load_hooks();
|
||||||
|
|
||||||
|
if (($argc <= 1) OR ($argv[1] != "no_cron")) {
|
||||||
|
poller_run_cron();
|
||||||
|
}
|
||||||
|
|
||||||
$a->start_process();
|
$a->start_process();
|
||||||
|
|
||||||
if ($a->min_memory_reached()) {
|
if ($a->min_memory_reached()) {
|
||||||
|
@ -55,11 +56,11 @@ function poller_run($argv, $argc){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($argc <= 1) OR ($argv[1] != "no_cron")) {
|
if ($a->max_processes_reached()) {
|
||||||
poller_run_cron();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($a->max_processes_reached()) {
|
if (!Lock::set('poller_worker')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +70,8 @@ function poller_run($argv, $argc){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lock::remove('poller_worker');
|
||||||
|
|
||||||
$starttime = time();
|
$starttime = time();
|
||||||
|
|
||||||
while ($r = poller_worker_process()) {
|
while ($r = poller_worker_process()) {
|
||||||
|
@ -83,12 +86,18 @@ function poller_run($argv, $argc){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Lock::set('poller_worker')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Count active workers and compare them with a maximum value that depends on the load
|
// Count active workers and compare them with a maximum value that depends on the load
|
||||||
if (poller_too_much_workers()) {
|
if (poller_too_much_workers()) {
|
||||||
logger('Active worker limit reached, quitting.', LOGGER_DEBUG);
|
logger('Active worker limit reached, quitting.', LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lock::remove('poller_worker');
|
||||||
|
|
||||||
if (!poller_execute($r[0])) {
|
if (!poller_execute($r[0])) {
|
||||||
logger('Process execution failed, quitting.', LOGGER_DEBUG);
|
logger('Process execution failed, quitting.', LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
|
@ -724,6 +733,8 @@ function poller_run_cron() {
|
||||||
if (array_search(__file__,get_included_files())===0){
|
if (array_search(__file__,get_included_files())===0){
|
||||||
poller_run($_SERVER["argv"],$_SERVER["argc"]);
|
poller_run($_SERVER["argv"],$_SERVER["argc"]);
|
||||||
|
|
||||||
|
Lock::removeAll();
|
||||||
|
|
||||||
poller_unclaim_process();
|
poller_unclaim_process();
|
||||||
|
|
||||||
get_app()->end_process();
|
get_app()->end_process();
|
||||||
|
|
|
@ -8,6 +8,8 @@ namespace Friendica\Util;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Friendica\Core\Config;
|
||||||
|
use Memcache;
|
||||||
use dba;
|
use dba;
|
||||||
use dbm;
|
use dbm;
|
||||||
|
|
||||||
|
@ -15,6 +17,31 @@ use dbm;
|
||||||
* @brief This class contain Functions for preventing parallel execution of functions
|
* @brief This class contain Functions for preventing parallel execution of functions
|
||||||
*/
|
*/
|
||||||
class Lock {
|
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
|
* @brief Sets a lock for a given name
|
||||||
|
@ -33,6 +60,33 @@ class Lock {
|
||||||
$got_lock = false;
|
$got_lock = false;
|
||||||
$start = time();
|
$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 {
|
do {
|
||||||
dba::lock('locks');
|
dba::lock('locks');
|
||||||
$lock = dba::select('locks', array('locked', 'pid'), array('name' => $fn_name), array('limit' => 1));
|
$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
|
* @param string $fn_name Name of the lock
|
||||||
*/
|
*/
|
||||||
public static function remove($fn_name) {
|
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()));
|
dba::update('locks', array('locked' => false, 'pid' => 0), array('name' => $fn_name, 'pid' => getmypid()));
|
||||||
return;
|
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…
Reference in a new issue