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:23:10 +00:00
parent 8edd27dcdc
commit 55244dc6d9
2 changed files with 33 additions and 52 deletions

View File

@ -1,27 +1,17 @@
#!/usr/bin/php -q #!/usr/bin/php -q
<?php <?php
/**************************************************************************\ /**
* eGroupWare API - Timed Asynchron Services for 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 * * @link http://www.egroupware.org
* -------------------------------------------------------------------------* * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* This library is part of the eGroupWare API * * @copyright Ralf Becker <RalfBecker-AT-outdoor-training.de>
* http://www.egroupware.org/ * *
* ------------------------------------------------------------------------ * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* This library is free software; you can redistribute it and/or modify it * * @package api
* under the terms of the GNU Lesser General Public License as published by * * @access public
* the Free Software Foundation; either version 2.1 of the License, * * @version $Id$
* 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$ */
$_GET['domain'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 'default'; $_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 $path_to_egroupware = realpath(dirname(__FILE__).'/../..'); // need to be adapted if this script is moved somewhere else
@ -68,11 +58,12 @@
exit(1); exit(1);
} }
include(PHPGW_API_INC.'/functions.inc.php'); include(EGW_API_INC.'/functions.inc.php');
$num = ExecMethod('phpgwapi.asyncservice.check_run','crontab'); $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) // if the following comment got removed, you will get an email from cron for every check performed (*nix only)
//echo $msg; //echo $msg;
@ -82,4 +73,4 @@
fwrite($f,$msg); fwrite($f,$msg);
fclose($f); 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 $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 * @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='') 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"; //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##')) if ($exists = $this->read('##last-check-run##'))
{ {
list(,$last_run) = each($exists); list(,$last_run) = each($exists);
@ -347,26 +340,21 @@ class asyncservice
{ {
return $last_run['data']; 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 $where = array();
//echo "<p>An other instance is running !!!</p>\n";
return False;
}
// no other instance runs ==> we should run
//
if ($release) if ($release)
{ {
$last_run['next'] = 0;
$last_run['data']['end'] = time(); $last_run['data']['end'] = time();
} }
else else
{ {
@set_time_limit(0); // dont stop for an execution-time-limit
ignore_user_abort(True);
$last_run = array( $last_run = array(
'id' => '##last-check-run##', 'id' => '##last-check-run##',
'next' => 0, 'next' => time(),
'times' => array(), 'times' => array(),
'method' => 'none', 'method' => 'none',
'data' => array( 'data' => array(
@ -375,13 +363,12 @@ class asyncservice
'end' => 0 '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"; //echo "last_run=<pre>"; print_r($last_run); echo "</pre>\n";
$this->write($last_run,!!$exits); return $this->write($last_run,!!$exits,$where) > 0;
$this->db->unlock();
return True;
} }
/** /**
@ -448,7 +435,7 @@ class asyncservice
} }
$this->last_check_run(True,True,$run_by); // release semaphore $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 array $job db-row as array
* @param boolean $exits if True, we do an update, else we check if update or insert necesary * @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( $data = array(
'async_next' => $job['next'], 'async_next' => $job['next'],
@ -520,6 +509,7 @@ class asyncservice
{ {
$this->db->insert($this->db_table,$data,array('async_id' => $job['id']),__LINE__,__FILE__); $this->db->insert($this->db_table,$data,array('async_id' => $job['id']),__LINE__,__FILE__);
} }
return $this->db->affected_rows();
} }
/** /**