Source of file BackgroundJob.php
Size: 4,048 Bytes - Last Modified: 2021-12-24T05:18:55+00:00
/var/www/docs.ssmods.com/process/src/src/Cron/BackgroundJob.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 | <?php namespace IQnection\BigCommerceApp\Cron; use SilverStripe\ORM\DataObject; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\ClassInfo; class BackgroundJob extends DataObject { const STATUS_OPEN = 'open'; const STATUS_RUNNING = 'running'; const STATUS_COMPLETE = 'complete'; const STATUS_FAILED = 'failed'; const STATUS_CANCELLED = 'cancelled'; private static $table_name = 'BCBackgroundJob'; private static $db = [ 'Name' => 'Varchar(255)', 'CallClass' => 'Varchar(255)', 'CallMethod' => 'Varchar(255)', 'Args' => 'Text', 'Status' => "Enum('open,running,complete,failed,cancelled','open')", 'CompleteDate' => 'Datetime', 'Hash' => 'Varchar(255)', 'Logs' => 'Text' ]; private static $defaults = [ 'Status' => 'open' ]; public function getTitle() { return $this->CallClass.'::'.$this->CallMethod; } public function StatusDisplay() { switch($this->Status) { case self::STATUS_OPEN: return 'Pending'; case self::STATUS_RUNNING: return 'Running'; case self::STATUS_CANCELLED: return 'Cancelled'; case self::STATUS_COMPLETE: return 'Last Synced: '.$this->dbObject('CompleteDate')->Nice(); } } public static function CreateJob($class, $method, $args = [], $name = null, $hash = null) { if (!$hash) { $hash = md5(json_encode([$class, $method, $args])); } if ($existing = self::get()->Filter(['Hash' => $hash, 'Status' => ['open','running']])->First()) { // make sure the job isn't stuck, give it a one hour buffer if (strtotime($existing->LastEdited) > strtotime('-1 hour')) { return $existing; } $existing->Status = self::STATUS_FAILED; $existing->write(); } $job = new self; $job->CallClass = $class; $job->CallMethod = $method; $job->Args = json_encode($args); $job->Status = self::STATUS_OPEN; $job->Hash = $hash; $job->Name = $name; $job->write(); return $job; } public function Run() { $this->Status = self::STATUS_RUNNING; $this->write(); if ( (!defined('BACKGROUND_JOBS_VERBOSE')) || (!BACKGROUND_JOBS_VERBOSE) ) { ob_start(); } try { // no methods should be static, create an instance of the class $className = ClassInfo::class_name($this->CallClass); $args = json_decode($this->Args,1); $inst = Injector::inst()->create($className); // if we're provided an ID, get teh specific model if ($inst instanceof DataObject) { if ( (isset($args['BigID'])) && ($dbInst = $className::get()->Find('BigID',$args['BigID'])) ) { $inst = $dbInst; } elseif ( (isset($args['ID'])) && ($dbInst = $className::get()->byID($args['ID'])) ) { $inst = $dbInst; } } if (!ClassInfo::hasMethod($inst, $this->CallMethod)) { throw new \Exception('Method '.$this->CallMethod.' does not exist in class '.$className,500); } $result = call_user_func_array([$inst, $this->CallMethod], [$args]); $this->Status = self::STATUS_COMPLETE; } catch (\Exception $e) { $this->Logs .= "\n".$e->getMessage()."\n\n".$e->getTraceAsString(); $this->Status = self::STATUS_FAILED; } $this->CompleteDate = date('Y-m-d H:i:s'); if ( (!defined('BACKGROUND_JOBS_VERBOSE')) || (!BACKGROUND_JOBS_VERBOSE) ) { $this->Logs .= "\nOutput:\n".ob_get_contents(); ob_end_clean(); } $this->write(); if (($this->Status == self::STATUS_COMPLETE) && ($this->Name)) { // mark any duplicate jobs as cancelled foreach(BackgroundJob::get()->Filter(['Name' => $this->Name, 'Status' => self::STATUS_OPEN]) as $dupJob) { $dupJob->Status == self::STATUS_CANCELLED; $dupJob->write(); } } if ((isset($e)) && ($e instanceof \Exception)) { throw $e; } return $this; } public static function RunJob($job) { return $job->Run(); } public static function NextJob() { return BackgroundJob::get()->Filter('Status', self::STATUS_OPEN)->Sort('Created','ASC')->First(); } public static function getOpen() { return BackgroundJob::get()->Filter('Status', self::STATUS_OPEN)->Sort('Created','ASC'); } } |