Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sat, Feb 22, 12:07 AM

in-portal

Index: branches/5.2.x/core/kernel/managers/scheduled_task_manager.php
===================================================================
--- branches/5.2.x/core/kernel/managers/scheduled_task_manager.php (revision 16664)
+++ branches/5.2.x/core/kernel/managers/scheduled_task_manager.php (revision 16665)
@@ -1,223 +1,244 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2010 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kScheduledTaskManager extends kBase implements kiCacheable {
/**
* Events, that should be run after parser initialization
*
* @var Array
* @access protected
*/
protected $tasks = Array ();
/**
* Sets data from cache to object
*
* @param Array $data
* @access public
*/
public function setFromCache(&$data)
{
$this->tasks = $data['EventManager.scheduledTasks'];
}
/**
* Gets object data for caching
*
* @return Array
* @access public
*/
public function getToCache()
{
return Array (
'EventManager.scheduledTasks' => $this->tasks,
);
}
/**
* Returns information about registered scheduled tasks
*
* @param bool $from_cache
* @return Array
* @access public
*/
public function getAll($from_cache = false)
{
static $scheduled_tasks = null;
if ( $from_cache ) {
return $this->tasks;
}
if ( !isset($scheduled_tasks) ) {
$timeout_clause = 'LastRunStatus = ' . ScheduledTask::LAST_RUN_RUNNING . ' AND Timeout > 0 AND ' . adodb_mktime() . ' - LastRunOn > Timeout';
$sql = 'SELECT *
FROM ' . $this->Application->getUnitOption('scheduled-task', 'TableName') . '
WHERE (Status = ' . STATUS_ACTIVE . ') AND ((LastRunStatus != ' . ScheduledTask::LAST_RUN_RUNNING . ') OR (' . $timeout_clause . '))';
$scheduled_tasks = $this->Conn->Query($sql, 'Name');
}
return $scheduled_tasks;
}
/**
* Add new scheduled task
*
* @param string $short_name name to be used to store last maintenance run info
* @param string $event_string
* @param int $run_schedule run schedule like for Cron
* @param int $status
* @access public
*/
public function add($short_name, $event_string, $run_schedule, $status = STATUS_ACTIVE)
{
$this->tasks[$short_name] = Array (
'Event' => $event_string, 'RunSchedule' => $run_schedule, 'Status' => $status
);
}
/**
* Run registered scheduled tasks with specified event type
*
* @param bool $from_cron
* @access public
*/
public function runAll($from_cron = false)
{
if ( defined('IS_INSTALL') ) {
return ;
}
$use_cron = $this->Application->ConfigValue('RunScheduledTasksFromCron');
if ( ($use_cron && !$from_cron) || (!$use_cron && $from_cron) ) {
// match execution place with one, set in config
return ;
}
ignore_user_abort(true);
set_time_limit(0);
$events_source = $this->getAll();
$user_id = $this->Application->RecallVar('user_id');
$this->Application->StoreVar('user_id', USER_ROOT, true); // to prevent permission checking inside events, true for optional storage
/** @var SiteHelper $site_helper */
$site_helper = $this->Application->recallObject('SiteHelper');
$site_domain_id = $site_helper->getDomainByName('DomainName', DOMAIN);
foreach ($events_source as $short_name => $event_data) {
+ // Scheduled task was updated from another process.
+ if ( $this->getLiveData($short_name) != $event_data ) {
+ continue;
+ }
+
if ( $site_domain_id && $event_data['SiteDomainLimitation'] != '' ) {
$site_domains = explode('|', substr($event_data['SiteDomainLimitation'], 1, -1));
if ( !in_array($site_domain_id, $site_domains) ) {
// scheduled task isn't allowed on this site domain
continue;
}
}
// remember LastTimeoutOn only for events that are still running and will be reset
if ( $event_data['LastRunStatus'] == ScheduledTask::LAST_RUN_RUNNING ) {
$this->update($short_name, Array ('LastTimeoutOn' => adodb_mktime()));
}
$next_run = (int)$event_data['NextRunOn'];
if ($next_run && ($next_run > adodb_mktime())) {
continue;
}
$event_data['Name'] = $short_name;
$this->run($event_data);
}
$this->Application->StoreVar('user_id', $user_id, $user_id == USER_GUEST);
}
/**
+ * Returns LIVE scheduled task data.
+ *
+ * @param string $short_name Short scheduled task name.
+ *
+ * @return array
+ */
+ protected function getLiveData($short_name)
+ {
+ $sql = 'SELECT *
+ FROM ' . $this->Application->getUnitOption('scheduled-task', 'TableName') . '
+ WHERE Status = ' . STATUS_ACTIVE . ' AND Name = ' . $this->Conn->qstr($short_name);
+
+ return $this->Conn->GetRow($sql);
+ }
+
+ /**
* Runs scheduled task based on given data
*
* @param Array $scheduled_task_data
* @return bool
* @access public
*/
public function run($scheduled_task_data)
{
$event = new kEvent($scheduled_task_data['Event']);
if ( !$this->Application->prefixRegistred($event->Prefix) ) {
// don't process scheduled tasks, left from disabled modules
return false;
}
/** @var kCronHelper $cron_helper */
$cron_helper = $this->Application->recallObject('kCronHelper');
$start_time = adodb_mktime();
// remember, when scheduled task execution started
$fields_hash = Array (
'LastRunOn' => $start_time,
'LastRunStatus' => ScheduledTask::LAST_RUN_RUNNING,
'NextRunOn' => $cron_helper->getMatch($scheduled_task_data['RunSchedule'], $start_time),
);
$this->update($scheduled_task_data['Name'], $fields_hash);
$event->redirect = false;
$this->Application->HandleEvent($event);
$now = adodb_mktime();
$next_run = $cron_helper->getMatch($scheduled_task_data['RunSchedule'], $start_time);
while ($next_run < $now) {
// in case event execution took longer, then RunSchedule (don't use <=, because RunSchedule can be 0)
$next_run = $cron_helper->getMatch($scheduled_task_data['RunSchedule'], $next_run);
}
// remember, when scheduled task execution ended
$fields_hash = Array (
'NextRunOn' => $next_run,
'RunTime' => $now - $start_time,
'LastRunStatus' => $event->status == kEvent::erSUCCESS ? ScheduledTask::LAST_RUN_SUCCEEDED : ScheduledTask::LAST_RUN_FAILED,
);
$this->update($scheduled_task_data['Name'], $fields_hash);
return true;
}
/**
* Updates scheduled task record with latest changes about it's invocation progress
*
* @param string $scheduled_task_name
* @param Array $fields_hash
* @return void
* @access protected
*/
protected function update($scheduled_task_name, $fields_hash)
{
$this->Conn->doUpdate(
$fields_hash,
$this->Application->getUnitOption('scheduled-task', 'TableName'),
'Name = ' . $this->Conn->qstr($scheduled_task_name)
);
}
-}
\ No newline at end of file
+}

Event Timeline