Update TaskManager to be a bit easier to extend

This commit is contained in:
Duncan Sommerville 2015-09-22 20:21:19 -04:00
parent 576a457fdb
commit ee1ceb9281
2 changed files with 47 additions and 46 deletions

View File

@ -149,7 +149,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
*/ */
if (getenv("AIRTIME_UNIT_TEST") != 1) { if (getenv("AIRTIME_UNIT_TEST") != 1) {
$taskManager = TaskManager::getInstance(); $taskManager = TaskManager::getInstance();
$taskManager->runTask(AirtimeTask::UPGRADE); // Run the upgrade on each request (if it needs to be run) $taskManager->runTask(TaskFactory::UPGRADE); // Run the upgrade on each request (if it needs to be run)
//This will do the upgrade too if it's needed... //This will do the upgrade too if it's needed...
$taskManager->runTasks(); $taskManager->runTasks();
} }

View File

@ -3,8 +3,8 @@
/** /**
* Class TaskManager * Class TaskManager
* *
* When adding a new task, the new AirtimeTask class will need to be added to the internal task list, * When adding a new task, the new AirtimeTask class will also need to be added
* as an ENUM value to the AirtimeTask interface, and as a case in the TaskFactory. * as a class constant and to the array in TaskFactory
*/ */
final class TaskManager { final class TaskManager {
@ -12,10 +12,7 @@ final class TaskManager {
* @var array tasks to be run. Maps task names to a boolean value denoting * @var array tasks to be run. Maps task names to a boolean value denoting
* whether the task has been checked/run * whether the task has been checked/run
*/ */
protected $_taskList = [ protected $_taskList;
AirtimeTask::UPGRADE => false,
AirtimeTask::CELERY => false,
];
/** /**
* @var TaskManager singleton instance object * @var TaskManager singleton instance object
@ -25,7 +22,7 @@ final class TaskManager {
/** /**
* @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks * @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks
*/ */
const TASK_INTERVAL_SECONDS = 30; const TASK_INTERVAL_SECONDS = 300; // 5 minutes - will be run on every pypo request
/** /**
* @var $con PDO Propel connection object * @var $con PDO Propel connection object
@ -36,6 +33,9 @@ final class TaskManager {
* Private constructor so class is uninstantiable * Private constructor so class is uninstantiable
*/ */
private function __construct() { private function __construct() {
foreach (array_keys(TaskFactory::$tasks) as $v) {
$this->_taskList[$v] = false;
}
} }
/** /**
@ -77,7 +77,7 @@ final class TaskManager {
*/ */
public function runTasks() { public function runTasks() {
// If there is data in auth storage, this could be a user request // If there is data in auth storage, this could be a user request
// so we should lock the TaskManager to avoid blocking // so we should just return to avoid blocking
if ($this->_isUserSessionRequest()) { if ($this->_isUserSessionRequest()) {
return; return;
} }
@ -85,7 +85,7 @@ final class TaskManager {
$this->_con->beginTransaction(); $this->_con->beginTransaction();
try { try {
$lock = $this->_getLock(); $lock = $this->_getLock();
if ($lock && microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS) { if ($lock && (microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS)) {
// Propel caches the database connection and uses it persistently, so if we don't // Propel caches the database connection and uses it persistently, so if we don't
// use commit() here, we end up blocking other queries made within this request // use commit() here, we end up blocking other queries made within this request
$this->_con->commit(); $this->_con->commit();
@ -96,8 +96,7 @@ final class TaskManager {
} catch (Exception $e) { } catch (Exception $e) {
// We get here if there are simultaneous requests trying to fetch the lock row // We get here if there are simultaneous requests trying to fetch the lock row
$this->_con->rollBack(); $this->_con->rollBack();
// Logging::info($e->getMessage()); // We actually get here a lot, so it's Logging::warn($e->getMessage());
// better to be silent here to avoid log bloat
return; return;
} }
foreach ($this->_taskList as $task => $hasTaskRun) { foreach ($this->_taskList as $task => $hasTaskRun) {
@ -154,14 +153,6 @@ final class TaskManager {
*/ */
interface AirtimeTask { interface AirtimeTask {
/**
* PHP doesn't have ENUMs so declare them as interface constants
* Task types - values don't really matter as long as they're unique
*/
const UPGRADE = "upgrade";
const CELERY = "celery";
/** /**
* Check whether the task should be run * Check whether the task should be run
* *
@ -178,31 +169,6 @@ interface AirtimeTask {
} }
/**
* Class TaskFactory Factory class to abstract task instantiation
*/
class TaskFactory {
/**
* Get an AirtimeTask based on a task type
*
* @param $task string the task type; uses AirtimeTask constants as an ENUM
*
* @return AirtimeTask|null return a task of the given type or null if no corresponding
* task exists or is implemented
*/
public static function getTask($task) {
switch($task) {
case AirtimeTask::UPGRADE:
return new UpgradeTask();
case AirtimeTask::CELERY:
return new CeleryTask();
}
return null;
}
}
/** /**
* Class UpgradeTask * Class UpgradeTask
*/ */
@ -247,4 +213,39 @@ class CeleryTask implements AirtimeTask {
CeleryManager::pollBrokerTaskQueue(); CeleryManager::pollBrokerTaskQueue();
} }
} }
/**
* Class TaskFactory Factory class to abstract task instantiation
*/
class TaskFactory {
/**
* PHP doesn't have ENUMs so declare them as interface constants
* Task types - values don't really matter as long as they're unique
*/
const UPGRADE = "upgrade";
const CELERY = "celery";
/**
* @var array map of arbitrary identifiers to class names to be instantiated reflectively
*/
public static $tasks = array(
"upgrade" => "UpgradeTask",
"celery" => "CeleryTask",
);
/**
* Get an AirtimeTask based on a task type
*
* @param $task string the task type; uses AirtimeTask constants as an ENUM
*
* @return AirtimeTask|null return a task of the given type or null if no corresponding
* task exists or is implemented
*/
public static function getTask($task) {
return new self::$tasks[$task]();
}
}