Ejemplo n.º 1
0
 private function runjobs()
 {
     if (!$this->storePath) {
         $this->storePath = TMP;
     }
     // look for a store of the previous run
     $store = "";
     $storeFilePath = $this->storePath . $this->storeFile;
     if (file_exists($storeFilePath)) {
         $store = file_get_contents($storeFilePath);
     }
     $this->out(date(DATE_SQL) . ' Reading from: ' . $storeFilePath);
     // build or rebuild the store
     if ($store != '') {
         $store = json_decode($store, true);
     } else {
         $store = $this->schedule;
     }
     App::import('Vendor', 'Fork', array('file' => 'duncan3dc/fork-helper/src/Fork.php'));
     $fork = new \duncan3dc\Helpers\Fork();
     //debug($this->schedule);
     //debug($store);
     // run the jobs that need to be run, record the time
     foreach ($this->schedule as $name => $job) {
         $now = new DateTime();
         $task = $job['task'];
         $action = $job['action'];
         // if the job has never been run before, create it
         if (!isset($store[$name])) {
             $store[$name] = $job;
         }
         // figure out the last run date
         $tmptime = $store[$name]['lastRun'];
         if ($tmptime == null) {
             $tmptime = new DateTime("1969-01-01 00:00:00");
         } elseif (is_array($tmptime)) {
             $tmptime = new DateTime($tmptime['date'], new DateTimeZone($tmptime['timezone']));
         } elseif (is_string($tmptime)) {
             $tmptime = new DateTime($tmptime);
         }
         $runNow = false;
         // determine the next run time based on the last
         if (substr($job['interval'], 0, 1) === 'P') {
             $tmptime->add(new DateInterval($job['interval']));
             // "P10DT4H" http://www.php.net/manual/en/class.dateinterval.php
             $runNow = $tmptime <= $now;
         } elseif (strtotime($job['interval']) !== false) {
             $tmptime->modify($job['interval']);
             // "next day 10:30" http://www.php.net/manual/en/datetime.formats.relative.php
             $runNow = $tmptime <= $now;
         } else {
             //cron expression
             //https://github.com/mtdowling/cron-expression
             $cron = Cron\CronExpression::factory($job['interval']);
             $runNow = $cron->getNextRunDate($tmptime) <= $now;
             $tmptime = $cron->getNextRunDate();
             //override for beter log readingz
         }
         $this->out('JOB ' . $job['name'] . ' next run time: ' . $tmptime->format(DATE_SQL));
         // is it time to run? has it never been run before? //aditionaly, is it currently running
         if ($runNow && empty($store[$name]['runningPID'])) {
             $this->out(date(DATE_SQL) . " Running {$name} --------------------------------------- ");
             if (!isset($this->{$task})) {
                 $this->{$task} = $this->Tasks->load($task);
                 // load models if they aren't already
                 foreach ($this->{$task}->uses as $mk => $mv) {
                     if (!isset($this->{$task}->{$mv})) {
                         App::uses('AppModel', 'Model');
                         App::uses($mv, 'Model');
                         $this->{$task}->{$mv} = new $mv();
                     }
                 }
             }
             // grab the entire schedule record incase it was updated..
             $store[$name] = $this->schedule[$name];
             // execute the task and store the result
             //$store[$name]['lastResult'] = call_user_func_array(array($this->$task, $action), $job['args']);
             //$reportInvoicesTask = $this->Tasks->load('ReportInvoices');
             //$fork->call(array($reportInvoicesTask,"execute"),array('2014-01-01 00:00:00','2016-01-01 00:00:00',"invoiceDaily"));
             //$store[$name]['lastResult'] = $fork->call(array($this->$task, $action), $job['args']);
             $store[$name]['runningPID'] = $fork->call(array($this->{$task}, $action), $job['args']);
             $this->out(date(DATE_SQL) . " Started {$name} as PID: " . $store[$name]['runningPID']);
             $this->activeThreads[] = $store[$name]['runningPID'];
             //unset($reportInvoicesTask);
             // assign it the current time
             $now = new DateTime();
             $store[$name]['lastRun'] = $now->format('Y-m-d H:i:s');
         }
     }
     // write the store back to the file
     file_put_contents($this->storePath . $this->storeFile, json_encode($store));
     $this->out(date(DATE_SQL) . ' All pending tasks are no longer pending');
     //$runningProcesses=Hash::extract($store,"{s}.runningPID");
     //debug($runningProcesses);
     for ($pcnt = 0; $pcnt < count($this->activeThreads); $pcnt++) {
         try {
             $endedPID = $fork->waitAny();
             $store = file_get_contents($storeFilePath);
             $store = json_decode($store, true);
             foreach ($store as $v) {
                 if ($v['runningPID'] == $endedPID) {
                     $finishedTask = $v;
                     break;
                 }
             }
             $this->out(date(DATE_SQL) . " Ended " . $finishedTask['name'] . " as PID: " . $endedPID);
             $store[$finishedTask['name']]['runningPID'] = null;
             file_put_contents($this->storePath . $this->storeFile, json_encode($store));
         } catch (Exception $e) {
             $message = $e->getMessage();
             $endedPID = $e->getCode();
             $store = file_get_contents($storeFilePath);
             $store = json_decode($store, true);
             foreach ($store as $v) {
                 if ($v['runningPID'] == $endedPID) {
                     $finishedTask = $v;
                     break;
                 }
             }
             $this->out(date(DATE_SQL) . " Ended " . $finishedTask['name'] . " as PID: " . $endedPID . " with EXCEPTION: \n" . $message);
             $store[$finishedTask['name']]['runningPID'] = null;
             $store[$finishedTask['name']]['lastResult'] = $message;
             file_put_contents($this->storePath . $this->storeFile, json_encode($store));
         }
     }
 }