protected function _executeTask(Engine_Db_Table_Row $task) { // Return if we reached our limit if ($this->_runCount >= $this->getMaxJobs()) { return $this; } // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log('Task Execution Check: ' . $task->title, Zend_Log::NOTICE); } // Update task using where (this will prevent double executions) $affected = $task->getTable()->update(array('state' => 'active', 'executing' => 1, 'executing_id' => $this->getPid(), 'started_last' => time(), 'started_count' => new Zend_Db_Expr('started_count + 1')), array('task_id = ?' => $task->task_id, 'state = ?' => $task->state, 'executing = ?' => 0, 'executing_id = ?' => 0)); // Refresh $task->refresh(); // If not affected cancel if ($affected !== 1) { // $task->executing_id != $this->getPid() return $this; } // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log('Task Execution Pass: '******'Core_Plugin_Task_Abstract')) { $this->getLog()->log(sprintf('Task plugin %1$s should extend Core_Plugin_Task_Abstract', $task->plugin), Zend_Log::WARN); // Execute plugin $plugin = Engine_Api::_()->loadClass($task->plugin); if (method_exists($plugin, 'execute')) { $plugin->execute(); } else { if (method_exists($plugin, 'executeTask')) { $plugin->executeTask(); } else { throw new Engine_Exception('Task ' . $task->plugin . ' does not have an execute or executeTask method'); } } } else { // Create plugin object $pluginClass = $task->plugin; $plugin = new $pluginClass($task); $plugin->setLog($this->getLog()); // Execute $plugin->execute(); // Ask semi auto ones if they are done yet if ($task->type == 'semi-automatic' && ($plugin instanceof Core_Plugin_Task_PersistentAbstract || method_exists($plugin, 'isComplete'))) { $isComplete = (bool) $plugin->isComplete(); } // Check was idle $wasIdle = $plugin->wasIdle(); } $status = true; } catch (Exception $e) { // Log exception $this->getLog()->log($e->__toString(), Zend_Log::ERR); $status = false; } // Update task if (!$isComplete) { $task->state = 'sleeping'; } else { $task->state = 'dormant'; } $task->executing = false; $task->executing_id = 0; $task->completed_count++; $task->completed_last = time(); if ($status) { $task->success_count++; $task->success_last = time(); } else { $task->failure_count++; $task->failure_last = time(); } $task->save(); // Update count if (!$wasIdle) { $this->_runCount++; } // Remove executing task $this->_executingTask = null; // Log if (APPLICATION_ENV == 'development') { if ($status) { $this->getLog()->log('Task Execution Complete: ' . $task->title, Zend_Log::NOTICE); } else { $this->getLog()->log('Task Execution Complete (with errors): ' . $task->title, Zend_Log::NOTICE); } } return $this; }
protected function _executeTaskCheck(Engine_Db_Table_Row $task) { // We've executed at least as many tasks as count if ($this->_runCount >= $this->_config['count']) { return false; } // We've reached the time limit for this request if (microtime(true) >= _ENGINE_REQUEST_START + $this->_config['time']) { return false; } // Task 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; } } // If semaphore limit is reached, and the timeout // has been reached, check if lock needs to be cleared if ($task->semaphore >= $task->processes) { // Sanity - wth is this? if ($task->processes < 1) { $task->processes = 1; $task->save(); return false; } // Get all processes matching task plugin $taskProcesses = $this->getAdapter()->select()->from('engine4_core_processes')->where('name = ?', $task->plugin)->query()->fetchAll(); // There was nothing, flush mutexes if (empty($taskProcesses)) { $affected = $this->update(array('semaphore' => new Zend_Db_Expr(sprintf('semaphore - %d', $task->semaphore))), array('task_id = ?' => $task->task_id)); if (1 !== $affected) { // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Execution Mutex Flush Failed [%d] : %s', $this->_pid, $task->title), Zend_Log::DEBUG); } return false; } } else { $activeProcesses = 0; foreach ($taskProcesses as $process) { $started = !empty($process['started']) ? $process['started'] : 0; $timeout = !empty($process['timeout']) ? $process['timeout'] : $this->_config['timeout']; // It's timed out if (time() > $started + $timeout) { // Delete $this->getAdapter()->delete('engine4_core_processes', array('pid' => $process['pid'])); // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Process Timeout [%d] : %d ', $this->_pid, $process['pid']), Zend_Log::DEBUG); } continue; } $activeProcesses++; } if ($activeProcesses >= $task->processes) { // Log if (APPLICATION_ENV == 'development') { $this->getLog()->log(sprintf('Execution Process Flush Failed [%d] : %d ', $this->_pid, $activeProcesses), Zend_Log::DEBUG); } return false; } } } // Task is ready return true; }