public function shouldTaskExecute(Engine_Db_Table_Row $task, $refresh = true, $isAutomatic = false) { // Refresh to check if run in separate thread if ($refresh) { $task->refresh(); } // Don't run it if it's disabled if (!$task->enabled || $task->type == 'disabled') { return false; } // Don't start manual tasks in automatic mode when they're dormant if (in_array($task->type, array('manual', 'semi-automatic')) && $task->state == 'dormant') { return false; } // Don't start executing tasks again unless they have been executing for > 15 minutes // We assume that 15 min means they have died and failed to cancel executing status if ($task->executing || $task->state == 'active') { if (time() > $task->started_last + $this->getTimeout()) { // Update the task, assuming it has timed out $newState = $task->type == 'semi-automatic' ? 'sleeping' : 'dormant'; $task->getTable()->update(array('state' => $newState, 'executing' => false, 'executing_id' => 0), array('task_id = ?' => $task->task_id, 'state = ?' => $task->state, 'executing = ?' => $task->executing, 'executing_id = ?' => $task->executing_id)); } return false; } // Tasks is not ready to be executed again yet if ($task->timeout > 0) { if (time() < $task->started_last + $task->timeout) { return false; } if (time() < $task->completed_last + $task->timeout) { return false; } } // Task is dormant if ($task->state == 'dormant') { // Automatic task is ready if ($task->type == 'automatic') { $task->getTable()->update(array('state' => 'ready'), array('task_id = ?' => $task->task_id, 'state = ?' => $task->state)); } return false; } // Sanity check if ($task->state != 'ready' && $task->state != 'sleeping') { $this->getLog()->log('Weird task state: ' . $task->state, Zend_Log::WARN); return false; } // Task is ready return true; }
protected function _executeTask(Engine_Db_Table_Row $task) { // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Task Execution Check [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } // Task execution semaphore $affected = $this->update(array('started_last' => time(), 'started_count' => new Zend_Db_Expr('started_count + 1'), 'semaphore' => new Zend_Db_Expr('semaphore + 1')), array('task_id = ?' => $task->task_id, 'semaphore < ?' => new Zend_Db_Expr('processes'))); if (1 !== $affected) { if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Task Execution Failed Semaphore [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } return false; } // Update process identifier $affected = $this->getAdapter()->update('engine4_core_processes', array('name' => $task->plugin), array('pid = ?' => $this->_pid)); if (1 !== $affected) { // Wth? if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Execution Failed Process Update [%d] : %s', $this->_pid, $task->plugin), Zend_Log::DEBUG); } } // Debug: sleeppre $slept = 0; if ($this->getParam('sleeppre', 0) > 0) { $slept += $this->getParam('sleeppre'); sleep($this->getParam('sleeppre')); } // Refresh $task->refresh(); // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Task Execution Pass [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } // ----- MAIN ----- // Set executing task $this->_executingTask = $task; // Invoke plugin $status = false; $isComplete = true; $wasIdle = false; try { // Get plugin object $plugin = $this->getTaskPlugin($task); // Execute $plugin->execute(); // Check was idle $wasIdle = $plugin->wasIdle(); // Ok $status = true; } catch (Exception $e) { // Log exception $this->getLog()->log($e->__toString(), Zend_Log::ERR); $status = false; } // ----- MAIN ----- // Debug: sleeppost if ($this->getParam('sleeppost', 0) > 0) { $slept += $this->getParam('sleeppost'); sleep($this->getParam('sleeppost')); } if (!isset($this->slept)) { $this->slept = 0; } $this->slept += $slept; // Update process identifier $affected = $this->getAdapter()->update('engine4_core_processes', array('name' => ''), array('pid = ?' => $this->_pid)); if (1 !== $affected) { // Wth? if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Execution Failed Process Update (post) [%d] : %s', $this->_pid, $task->plugin), Zend_Log::DEBUG); } } // Update task and release semaphore $statusKey = $status ? 'success' : 'failure'; $affected = $this->update(array('semaphore' => new Zend_Db_Expr('semaphore - 1'), 'completed_last' => time(), 'completed_count' => new Zend_Db_Expr('completed_count + 1'), $statusKey . '_last' => time(), $statusKey . '_count' => new Zend_Db_Expr($statusKey . '_count + 1')), array('task_id = ?' => $task->task_id, 'semaphore > ?' => 0)); if (1 !== $affected) { if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Task Execution Failed Semaphore Release [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } return false; } // Update count if (!$wasIdle) { $this->_runCount++; } // Remove executing task $this->_executingTask = null; // Log if (APPLICATION_ENV == 'development') { if ($status) { $this->getLog()->log(sprintf('Task Execution Complete [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } else { $this->getLog()->log(sprintf('Task Execution Complete with errors [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } } return $this; }