This commit is contained in:
Duncan Sommerville 2015-06-17 17:16:21 -04:00
parent 89e3eaa986
commit afb02301c1
2 changed files with 22 additions and 29 deletions

View File

@ -48,17 +48,27 @@ final class TaskManager {
} }
/** /**
* Run all tasks that need to be run * Run all tasks that need to be run.
*
* To prevent blocking and making too many requests to the database,
* we implement a row-level, non-blocking, read-protected lock on a
* timestamp that we check each time the application is bootstrapped,
* which, assuming enough time has passed, is updated before running
* the tasks.
*/ */
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 lock the TaskManager to avoid blocking
if ($this->_isUserSessionRequest()) return; if ($this->_isUserSessionRequest()) {
return;
}
$this->_con = Propel::getConnection(CcPrefPeer::DATABASE_NAME); $this->_con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
$this->_con->beginTransaction(); $this->_con->beginTransaction();
try { try {
$lock = $this->_getLock(); $lock = $this->_getLock();
if ($lock && microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS) return; if ($lock && microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS) {
return;
}
$this->_updateLock($lock); $this->_updateLock($lock);
$this->_con->commit(); $this->_con->commit();
} catch (Exception $e) { } catch (Exception $e) {
@ -70,14 +80,17 @@ final class TaskManager {
} }
foreach ($this->_taskList as $task) { foreach ($this->_taskList as $task) {
$task = TaskFactory::getTask($task); $task = TaskFactory::getTask($task);
if ($task && $task->shouldBeRun()) $task->run(); if ($task && $task->shouldBeRun()) {
$task->run();
}
} }
} }
/** /**
* Check if the current session is a user request * Check if the current session is a user request
* *
* @return bool * @return bool true if there is a Zend_Auth object in the current session,
* otherwise false
*/ */
private function _isUserSessionRequest() { private function _isUserSessionRequest() {
$auth = Zend_Auth::getInstance(); $auth = Zend_Auth::getInstance();
@ -88,6 +101,10 @@ final class TaskManager {
/** /**
* Get the task_manager_lock from cc_pref with a row-level lock for atomicity * Get the task_manager_lock from cc_pref with a row-level lock for atomicity
* *
* The lock is exclusive (prevent reads) and will only last for the duration
* of the transaction. We add NOWAIT so reads on the row during the transaction
* won't block
*
* @return array|bool an array containing the row values, or false on failure * @return array|bool an array containing the row values, or false on failure
*/ */
private function _getLock() { private function _getLock() {

View File

@ -10,30 +10,6 @@ class Application_Form_SoundcloudPreferences extends Zend_Form_SubForm
array('ViewScript', array('viewScript' => 'form/preferences_soundcloud.phtml')) array('ViewScript', array('viewScript' => 'form/preferences_soundcloud.phtml'))
)); ));
// $select = new Zend_Form_Element_Select('SoundCloudTrackType');
// $select->setLabel(_('Default Track Type:'));
// $select->setAttrib('class', 'input_select');
// $select->setMultiOptions(array(
// "" => "",
// "original" => _("Original"),
// "remix" => _("Remix"),
// "live" => _("Live"),
// "recording" => _("Recording"),
// "spoken" => _("Spoken"),
// "podcast" => _("Podcast"),
// "demo" => _("Demo"),
// "in progress" => _("Work in progress"),
// "stem" => _("Stem"),
// "loop" => _("Loop"),
// "sound effect" => _("Sound Effect"),
// "sample" => _("One Shot Sample"),
// "other" => _("Other")
// ));
// $select->setRequired(false);
// $select->setValue(Application_Model_Preference::GetSoundCloudTrackType());
// $select->setDecorators(array('ViewHelper'));
// $this->addElement($select);
$select = new Zend_Form_Element_Select('SoundCloudLicense'); $select = new Zend_Form_Element_Select('SoundCloudLicense');
$select->setLabel(_('Default License:')); $select->setLabel(_('Default License:'));
$select->setAttrib('class', 'input_select'); $select->setAttrib('class', 'input_select');