Current File : /pages/54/47/d0016649/home/htdocs/ob_maxi/wp-content/plugins/digimember/system/model/queue/base.php |
<?php
$load->modelClass( 'data/base' );
abstract class ncore_BaseQueue extends ncore_BaseData
{
const max_try_count=5;
public function execJob( $id )
{
ignore_user_abort(true);
$jobs_completed = 0;
while (true)
{
$row = $this->getAndLock( $id );
if ($row)
{
try
{
$success = $this->process( $row );
if ($success) {
$jobs_completed++;
}
}
catch( Exception $e )
{
$success = false;
}
$this->unLock( $row, $success);
}
else
{
break;
}
if ($id)
{
break;
}
}
return $jobs_completed;
}
public function cronMinutely()
{
$this->execJob( $id=false );
}
public function cronHourly()
{
$this->execJob( $id=false );
$tableName = $this->sqlTableName();
$now = ncore_dbDate();
$sql = "UPDATE `$tableName`
SET locked_at = NULL
WHERE locked_at < '$now' - INTERVAL 1 HOUR";
$this->db()->query($sql);
}
public function cronDaily()
{
$this->purgeQueue();
}
//
// protected section
//
abstract protected function process($data);
protected function keepTimeDays()
{
return 30;
}
protected function purgeQueue()
{
$days = $this->keepTimeDays();
if (!$days) {
return;
}
$tableName = $this->sqlTableName();
$expire_at = ncore_dbDate( time() - 86400 * $days );
$sql = "DELETE FROM `$tableName`
WHERE processed_at < '$expire_at'";
$this->db()->query($sql);
}
protected function sqlTableMeta()
{
$columns = array(
'processed_at' => 'lock_date',
'try_count' => 'int',
'next_try_at' => 'lock_date',
'locked_at' => 'lock_date'
);
$indexes = array(
'processed_at'
);
$meta = array(
'columns' => $columns,
'indexes' => $indexes
);
return $meta;
}
protected function defaultValues()
{
$values = parent::defaultValues();
$values[ 'try_count' ] = '0';
$values[ 'next_try_at' ] = '2010-01-01 00:00:00';
return $values;
}
abstract protected function onGiveUp( $row, $tries_so_far );
abstract protected function onFailure( $row, $tries_so_far, $tries_left );
//
// private section
//
private function getAndLock( $id=false )
{
$order_by = 'id ASC';
$where = array(
'processed_at' => null,
'locked_at' => null,
'next_try_at <' => ncore_dbDate(),
);
if ($this->hasTrash()) {
$where[ 'deleted' ] = null;
}
if ($id)
{
$where[ 'id' ] = $id;
}
$row = $this->getWhere($where, $order_by);
if (!$row)
{
return false;
}
$data = array(
'locked_at' => ncore_dbDate(),
);
$modified = $this->update($row->id, $data, $where);
if ($modified)
{
return $row;
}
return false;
}
private function unLock($row, $mark_as_finished)
{
if (is_array($mark_as_finished)) {
$data = $mark_as_finished;
$mark_as_finished = (bool) $mark_as_finished;
}
else
{
$data = array();
}
$data[ 'locked_at' ] = null;
if ($mark_as_finished==='ignore')
{
// empty
}
elseif ($mark_as_finished)
{
$data[ 'processed_at' ] = ncore_dbDate();
$data[ 'next_try_at' ] = null;
}
else
{
$tries_so_far = $row->try_count + 1;
$tries_left = self::max_try_count - $tries_so_far;
if ($tries_left <= 0)
{
$data[ 'processed_at' ] = ncore_dbDate();
$data[ 'next_try_at' ] = null;
$data[ 'try_count' ] = $tries_so_far;
$this->onGiveUp( $row, $tries_so_far );
}
else
{
$wait_hours = $this->waitHours( $tries_so_far );
$this->onFailure( $row, $tries_so_far, $tries_left );
$data[ 'next_try_at' ] = ncore_dbDate( time() + 3600 * $wait_hours );
$data[ 'try_count' ] = $tries_so_far;
}
}
$this->update($row->id, $data);
}
private function waitHours( $tries_so_far )
{
if ($tries_so_far <= 2)
{
$wait_hours = 2;
}
elseif ($tries_so_far <= 4)
{
$wait_hours = 12;
}
else
{
$wait_hours = 12;
}
return $wait_hours;
}
}