private function cycle() { // fire extender ready event $this->events->fire("extender", "VOID", $this); // dispatch signals (if multithread active) if ($this->getMultithreadMode()) { pcntl_signal_dispatch(); } // if extender is paused (SIGINT), skip to extend if ($this->paused) { return; } // fix relative timestamp $this->timestamp = microtime(true); // fire tasktable event $this->tasks = $this->events->fire("extender.tasks", "TASKSTABLE", $this->tasks); // get the next planned activity interval $plans = Planner::get(); if (!is_null($plans) and $this->timestamp < $plans) { // nothing to do right now, still waiting if in daemon mode $this->logger->info("Next planned job: " . date('c', $plans)); $this->logger->notice("Extender completed\n"); if ($this->getDaemonMode() === false) { $this->shutdown(true); self::end(0); } return; } // if no plan is retrieved, try to retrieve it from scheduler try { // get schedules and dispatch schedule event list($schedules, $planned) = Scheduler::getSchedules($this->logger, $this->timestamp); // write next planned activity interval if (!is_null($planned) and $planned != 0) { Planner::set($planned); } $scheduled = new Schedule(); $scheduled->setSchedules($schedules); // expose the current shcedule via events $scheduled = $this->events->fire("extender.schedule", "SCHEDULE", $scheduled); // if no jobs in queue, exit gracefully if ($scheduled->howMany() == 0) { $this->logger->info("No jobs to process right now, exiting"); $this->logger->notice("Extender completed\n"); if ($this->getDaemonMode() === false) { $this->shutdown(true); self::end(0); } return; } // compose jobs foreach ($scheduled->getSchedules() as $schedule) { if ($this->tasks->isRegistered($schedule['task'])) { $job = new Job(); $job->setName($schedule['name'])->setId($schedule['id'])->setParameters(unserialize($schedule['params']))->setTask($schedule['task'])->setClass($this->tasks->getClass($schedule['task'])); $this->runner->addJob($job); } else { $this->logger->warning("Skipping job due to unknown task", array("ID" => $schedule['id'], "NAME" => $schedule['name'], "TASK" => $schedule['task'])); } } // lauch runner $result = $this->runner->run(); // free runner for next cycle $this->runner->free(); // compose results $results = new JobsResult($result); // update schedules Scheduler::updateSchedules($this->logger, $result); // increment counters foreach ($result as $r) { if ($r[2]) { $this->completed_processes++; } else { $this->failed_processes++; } } } catch (Exception $e) { $this->logger->error($e->getMessage()); if ($this->getDaemonMode() === false) { self::end(1); } } // fire result event $this->events->fire("extender.result", "VOID", $results); $this->logger->notice("Extender completed\n"); // show summary (if -s) if ($this->summary_mode) { self::showSummary($this->timestamp, $result, $this->color); } Status::dump($this->timestamp_absolute, $this->parent_pid, $this->completed_processes, $this->failed_processes, $this->paused); if ($this->getDaemonMode() === false) { $this->shutdown(true); self::end(0); } }
/** * Add job to current queue * * @param \Comodojo\Extender\Job\Job $job An instance of \Comodojo\Extender\Job\Job * * @return string A job unique identifier */ public final function addJob(\Comodojo\Extender\Job\Job $job) { $uid = self::getJobUid(); try { $class = $job->getClass(); if (class_exists($class) === false) { throw new Exception("Task cannot be loaded"); } $this->jobs[$uid] = array("name" => $job->getName(), "id" => $job->getId(), "parameters" => $job->getParameters(), "task" => $job->getTask(), "class" => $class); } catch (Exception $e) { $this->logger->error('Error including job', array("JOBUID" => $uid, "ERROR" => $e->getMessage(), "ERRID" => $e->getCode())); return false; } return $uid; }