fixed not working semaphore in asyncservice (we are not supporting table locks anymore / since 1.2)

This commit is contained in:
Ralf Becker 2007-07-26 09:22:28 +00:00
parent 32b19397ae
commit 4f6b0ae2da
2 changed files with 33 additions and 52 deletions

View File

@ -1,27 +1,17 @@
#!/usr/bin/php -q
<?php
/**************************************************************************\
* eGroupWare API - Timed Asynchron Services for eGroupWare *
* Written by Ralf Becker <RalfBecker@outdoor-training.de> *
* Class for creating cron-job like timed calls of eGroupWare methods *
* -------------------------------------------------------------------------*
* This library is part of the eGroupWare API *
* http://www.egroupware.org/ *
* ------------------------------------------------------------------------ *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, *
* or any later version. *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
\**************************************************************************/
/* $Id$ */
/**
* API - Timed Asynchron Services for eGroupWare
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright Ralf Becker <RalfBecker-AT-outdoor-training.de>
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @access public
* @version $Id$
*/
$_GET['domain'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 'default';
$path_to_egroupware = realpath(dirname(__FILE__).'/../..'); // need to be adapted if this script is moved somewhere else
@ -68,11 +58,12 @@
exit(1);
}
include(PHPGW_API_INC.'/functions.inc.php');
include(EGW_API_INC.'/functions.inc.php');
$num = ExecMethod('phpgwapi.asyncservice.check_run','crontab');
$msg = date('Y/m/d H:i:s ').$_GET['domain'].': '.($num ? "$num job(s) executed" : 'Nothing to execute')."\n\n";
$msg = date('Y/m/d H:i:s ').$_GET['domain'].': '.($num === false ? 'An error occured: can not obtain semaphore!' :
($num ? "$num job(s) executed" : 'Nothing to execute'))."\n\n";
// if the following comment got removed, you will get an email from cron for every check performed (*nix only)
//echo $msg;
@ -82,4 +73,4 @@
fwrite($f,$msg);
fclose($f);
}
$GLOBALS['egw']->common->phpgw_exit();
$GLOBALS['egw']->common->egw_exit();

View File

@ -320,7 +320,7 @@ class asyncservice
}
/**
* checks when the last check_run was run or set the run-semaphore if $semaphore == True
* checks when the last check_run was run or set the run-semaphore (async_next != 0) if $semaphore == True
*
* @param boolean $semaphore if False only check, if true try to set/release the semaphore
* @param boolean $release if $semaphore == True, tells if we should set or release the semaphore
@ -330,13 +330,6 @@ class asyncservice
function last_check_run($semaphore=False,$release=False,$run_by='')
{
//echo "<p>last_check_run(semaphore=".($semaphore?'True':'False').",release=".($release?'True':'False').")</p>\n";
if ($semaphore)
{
$this->db->lock($this->db_table,'write'); // this will block til we get exclusive access to the table
@set_time_limit(0); // dont stop for an execution-time-limit
ignore_user_abort(True);
}
if ($exists = $this->read('##last-check-run##'))
{
list(,$last_run) = each($exists);
@ -347,26 +340,21 @@ class asyncservice
{
return $last_run['data'];
}
elseif (!$release && !$last_run['data']['end'] && $last_run['data']['start'] > time()-600)
{
// already one instance running (started not more then 10min ago, else we ignore it)
$this->db->unlock(); // unlock the table again
//echo "<p>An other instance is running !!!</p>\n";
return False;
}
// no other instance runs ==> we should run
//
$where = array();
if ($release)
{
$last_run['next'] = 0;
$last_run['data']['end'] = time();
}
else
{
@set_time_limit(0); // dont stop for an execution-time-limit
ignore_user_abort(True);
$last_run = array(
'id' => '##last-check-run##',
'next' => 0,
'next' => time(),
'times' => array(),
'method' => 'none',
'data' => array(
@ -375,13 +363,12 @@ class asyncservice
'end' => 0
)
);
// as the async_next column is used as a semaphore we only update it,
// if it is 0 (semaphore released) or older then 10min to recover from failed or crashed attempts
if ($exists) $where = array('async_next=0 OR async_next<'.time()-600);
}
//echo "last_run=<pre>"; print_r($last_run); echo "</pre>\n";
$this->write($last_run,!!$exits);
$this->db->unlock();
return True;
return $this->write($last_run,!!$exits,$where) > 0;
}
/**
@ -448,7 +435,7 @@ class asyncservice
}
$this->last_check_run(True,True,$run_by); // release semaphore
return $jobs ? count($jobs) : False;
return $jobs ? count($jobs) : 0;
}
/**
@ -502,8 +489,10 @@ class asyncservice
*
* @param array $job db-row as array
* @param boolean $exits if True, we do an update, else we check if update or insert necesary
* @param array $where additional where statemetn to update only if a certain condition is met, used for the semaphore
* @return int affected rows, cat be 0 if an additional where statement is given
*/
function write($job,$exists = False)
function write($job,$exists = False,$where=array())
{
$data = array(
'async_next' => $job['next'],
@ -520,6 +509,7 @@ class asyncservice
{
$this->db->insert($this->db_table,$data,array('async_id' => $job['id']),__LINE__,__FILE__);
}
return $this->db->affected_rows();
}
/**