/** * This method executes the given task and properly marks and records that execution * It is expected to return FALSE if the task was barred from running or if it was not saved properly * * @param Task\AbstractTask $task The task to execute * @return bool Whether the task was saved successfully to the database or not * @throws FailedExecutionException * @throws \Exception */ public function executeTask(Task\AbstractTask $task) { // Trigger the saving of the task, as this will calculate its next execution time // This should be calculated all the time, even if the execution is skipped // (in case it is skipped, this pushes back execution to the next possible date) $task->save(); // Set a scheduler object for the task again, // as it was removed during the save operation $task->setScheduler(); $result = true; // Task is already running and multiple executions are not allowed if (!$task->areMultipleExecutionsAllowed() && $task->isExecutionRunning()) { // Log multiple execution error $logMessage = 'Task is already running and multiple executions are not allowed, skipping! Class: ' . get_class($task) . ', UID: ' . $task->getTaskUid(); $this->log($logMessage); $result = false; } else { // Log scheduler invocation $logMessage = 'Start execution. Class: ' . get_class($task) . ', UID: ' . $task->getTaskUid(); $this->log($logMessage); // Register execution $executionID = $task->markExecution(); $failure = null; try { // Execute task $successfullyExecuted = $task->execute(); if (!$successfullyExecuted) { throw new FailedExecutionException('Task failed to execute successfully. Class: ' . get_class($task) . ', UID: ' . $task->getTaskUid(), 1250596541); } } catch (\Exception $e) { // Store exception, so that it can be saved to database $failure = $e; } // make sure database-connection is fine // for long-running tasks the database might meanwhile have disconnected $this->getDatabaseConnection()->isConnected(); // Un-register execution $task->unmarkExecution($executionID, $failure); // Log completion of execution $logMessage = 'Task executed. Class: ' . get_class($task) . ', UID: ' . $task->getTaskUid(); $this->log($logMessage); // Now that the result of the task execution has been handled, // throw the exception again, if any if ($failure instanceof \Exception) { throw $failure; } } return $result; }