public function testLocalServerPortNotUsed() { $url = $GLOBALS['sugar_config']['site_url'] . '/' . $this->_cron_test_file; $_SERVER['SERVER_PORT'] = '9090'; $sJob = new SchedulersJob(FALSE); $this->assertTrue($sJob->fireUrl($url)); }
public function testFlushDeadJobs() { $this->testScheduler->fire(); $this->testScheduler->status = 'In Progress'; $this->testScheduler->save(); $this->assertEquals('In Progress', $this->testScheduler->status, "Assert that the test scheduler instance has status of 'In Progress'"); $result = $GLOBALS['db']->query("SELECT id FROM schedulers_times WHERE scheduler_id ='{$this->testScheduler->id}'"); $jobCount = 0; while ($row = $GLOBALS['db']->fetchByAssoc($result)) { $job = new SchedulersJob(); $job->retrieve($row['id']); $this->assertEquals('completed', $job->status, "Assert that schedulers_times status is set to 'completed'"); $job->execute_time = $this->testScheduler->date_time_start; //Set this to the start time of the scheduler which is in year 2005 $job->save(); $jobCount++; } $this->assertTrue($jobCount > 0, "Assert that we created schedulers_times entries"); $this->testScheduler->flushDeadJobs(); $this->testScheduler->retrieve($this->testScheduler->id); $this->assertEquals('Active', $this->testScheduler->status, "Assert that the status for scheduler is set to 'Active'"); $result = $GLOBALS['db']->query("SELECT id FROM schedulers_times WHERE scheduler_id ='{$this->testScheduler->id}'"); while ($row = $GLOBALS['db']->fetchByAssoc($result)) { $job = new SchedulersJob(); $job->retrieve($row['id']); $this->assertEquals('failed', $job->status, "Assert that schedulers_times status is set to 'failed'"); } }
public function tearDown() { if (!empty($this->id)) { $job = new SchedulersJob(); $job->mark_deleted($this->id); } SugarTestHelper::tearDown(); }
protected function createJob($data) { $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_QUEUED; foreach ($data as $key => $val) { $job->{$key} = $val; } $job->save(); $this->jobs[] = $job->id; return $job; }
/** * This method implements the run function of RunnableSchedulerJob and handles processing a SchedulersJob * * @param Mixed $data parameter passed in from the job_queue.data column when a SchedulerJob is run * @return bool true on success, false on error */ public function run($data) { $systemInfo = $this->getSystemInfo(); if ($systemInfo->getActiveUsersXDaysCount(3) == 0) { if (!$this->sendHeartbeat($systemInfo->getInfo())) { $this->job->failJob("Unable to send heartbeat"); return false; } } $this->job->succeedJob(); return true; }
/** * @param $data * @return bool */ public function run($data) { $this->job->runnable_ran = true; $this->job->runnable_data = $data; $keys = json_decode(html_entity_decode($data), true); foreach ($keys as $key) { /* @var $opp RevenueLineItem */ $opp = BeanFactory::getBean('RevenueLineItems'); $opp->retrieve($key); $opp->save(false); } $this->job->succeedJob(); return true; }
/** * Submit a new job to the queue * * @param SchedulersJob $job Job object * * @return string Job ID */ public function submitJob($job) { $job->id = create_guid(); $job->new_with_id = true; $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->resolution = SchedulersJob::JOB_PENDING; if (empty($job->execute_time)) { $job->execute_time = $GLOBALS['timedate']->nowDb(); } if (empty($job->assigned_user_id)) { $job->assigned_user_id = $GLOBALS['current_user']->id; } $job->save(); return $job->id; }
/** * Dispatch request. * @param SugarBean $seed a bean that fired event * @param string $event event name * @param array $arguments event arguments * @param string $id web logic hook id */ public function dispatchRequest(SugarBean $seed, $event, $arguments, $id) { $this->retrieve($id); if (empty($this->id)) { return; } $jobData = array('url' => $this->url, 'request_method' => $this->request_method, 'payload' => $this->formatRequestData($seed, $event, $arguments)); $job = new SchedulersJob(); $job->assigned_user_id = $this->created_by; $job->name = 'Dispatch Web Logic Hook'; $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->target = 'class::' . get_class($this); $job->data = serialize($jobData); $job->save(); }
/** * Execute given job * @param SchedulersJob $job */ public function executeJob($job) { if (!$this->job->runJob()) { // if some job fails, change run status $this->jobFailed($this->job); } }
/** * @param string $data The job data set for this particular Scheduled Job instance * @return boolean true if the run succeeded; false otherwise */ public function run($data) { /* @var $admin Administration */ $admin = BeanFactory::getBean('Administration'); $settings = $admin->getConfigForModule('Forecasts'); if ($settings['is_setup'] == false) { $GLOBALS['log']->fatal("Forecast Module is not setup. " . __CLASS__ . " should not be running"); return false; } $args = json_decode(html_entity_decode($data), true); $this->job->runnable_ran = true; // use the processWorksheetDataChunk to run the code. ForecastWorksheet::processWorksheetDataChunk($args['forecast_by'], $args['data']); $this->job->succeedJob(); return true; }
/** * @param string $data The job data set for this particular Scheduled Job instance * @return boolean true if the run succeeded; false otherwise */ public function run($data) { $settings = Opportunity::getSettings(); if (isset($settings['opps_view_by']) && $settings['opps_view_by'] !== 'RevenueLineItems') { $GLOBALS['log']->fatal("Opportunity are not being used with Revenue Line Items. " . __CLASS__ . " should not be running"); return false; } $args = json_decode(html_entity_decode($data), true); $this->job->runnable_ran = true; // use the processWorksheetDataChunk to run the code. SugarAutoLoader::load('modules/Opportunities/include/OpportunityWithRevenueLineItem.php'); OpportunityWithRevenueLineItem::processOpportunityIds($args['data']); $this->job->succeedJob(); $this->notifyAssignedUser(); return true; }
public function testCleanup() { $job = new SchedulersJob(); $job->update_date_modified = false; $job->status = SchedulersJob::JOB_STATUS_RUNNING; $job->scheduler_id = 'unittest'; $job->execute_time = $GLOBALS['timedate']->nowDb(); $job->date_entered = $GLOBALS['timedate']->getNow()->modify("-1 day")->asDb(); $job->date_modified = $GLOBALS['timedate']->getNow()->modify("-10 minutes")->asDb(); $job->name = "Unit Test Job"; $job->target = "test::test"; $job->save(); $job_id = $job->id; $this->jq->cleanup(); $job = new SchedulersJob(); $job->retrieve($job_id); // Cleanup will always set job resolution to JOB_FAILURE when a job is cleaned $this->assertNotEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution"); }
/** * @param $data * @return bool */ public function run($data) { $this->job->runnable_ran = true; $this->job->runnable_data = $data; $data = json_decode($data, true); Activity::disable(); $ftsInstance = SugarSearchEngineFactory::getInstance(); $ftsInstance->setForceAsyncIndex(true); foreach ($data as $row) { /* @var $opp Opportunity */ $opp = BeanFactory::getBean('Opportunities', $row['id']); $opp->save(false); } $ftsInstance->setForceAsyncIndex(SugarConfig::getInstance()->get('search_engine.force_async_index', false)); Activity::enable(); $this->job->succeedJob(); $this->notifyAssignedUser(); return true; }
/** * Execute given job * @param SchedulersJob $job */ public function executeJob($job) { if (!$this->job->runJob()) { // if some job fails, change run status $this->jobFailed($this->job); } // If the job produced a session, destroy it - we won't need it anymore if (session_id()) { session_destroy(); } }
/** * @param string $data The job data set for this particular Scheduled Job instance * @return boolean true if the run succeeded; false otherwise */ public function run($data) { $settings = Opportunity::getSettings(); if (isset($settings['opps_view_by']) && $settings['opps_view_by'] !== 'Opportunities') { $GLOBALS['log']->fatal("Opportunity are being used with Revenue Line Items. " . __CLASS__ . " should not be running"); return false; } $args = json_decode(html_entity_decode($data), true); $this->job->runnable_ran = true; $labels = $args['labels']; $data = $args['chunk']; $currencies = array(); Activity::disable(); // disable the fts index as well /* @var $ftsSearch SugarSearchEngineElastic */ $ftsSearch = SugarSearchEngineFactory::getInstance(); $ftsSearch->setForceAsyncIndex(true); foreach ($data as $opp_id => $rli_data) { /* @var $opp Opportunity */ $opp = BeanFactory::getBean('Opportunities', $opp_id); /* @var $note Note */ $note = BeanFactory::getBean('Notes'); $note->parent_id = $opp_id; $note->parent_type = 'Opportunities'; $note->assigned_user_id = $opp->assigned_user_id; $note->created_by = $opp->created_by; $note->name = 'Previous Associated Revenue Line Items'; $desc = ''; foreach ($rli_data as $rli) { $desc .= $rli['name'] . "\n"; foreach ($rli as $field => $value) { if (isset($labels[$field])) { if ($field === 'currency_id') { if (!isset($currencies[$value])) { $currencies[$value] = SugarCurrency::getCurrencyByID($value); } $desc .= " - " . $labels[$field] . ": " . $currencies[$value]->name . "\n"; } elseif ($field !== 'name' && $field !== 'opportunity_id') { $desc .= " - " . $labels[$field] . ": " . $value . "\n"; } } } $desc .= "\n\n"; } $note->description = trim($desc); $note->save(); } // set it back to the default value from the config. $ftsSearch->setForceAsyncIndex(SugarConfig::getInstance()->get('search_engine.force_async_index', false)); Activity::enable(); $this->job->succeedJob(); $this->notifyAssignedUser(); return true; }
/** * @param $data * @return bool */ public function run($data) { $this->job->runnable_ran = true; $maxLifetime = $this->getMaxLifetime(); if (!$maxLifetime) { $this->job->failJob('File max lifetime is not configured'); return false; } $dir = $this->getDirectory(); if (!file_exists($dir)) { $this->job->succeedJob(); return true; } $files = $this->getFilesToRemove($dir, $maxLifetime); $result = $this->removeFiles($files); if ($result) { $this->job->succeedJob(); } else { $this->job->failJob(); } return $result; }
/** * Execute given job * @param SchedulersJob $job */ public function executeJob($job) { $this->setTimeLimit($this->max_runtime); $res = $this->job->runJob(); $this->clearTimeLimit(); if (!$res) { // if some job fails, change run status $this->jobFailed($this->job); } // If the job produced a session, destroy it - we won't need it anymore if (session_id()) { session_destroy(); } }
public function testCleanupJobs() { $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser(); $this->scheduler = new Scheduler(false); $this->scheduler->id = create_guid(); $newjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE, "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id, "scheduler_id" => $this->scheduler->id)); $oldjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE, "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id, "scheduler_id" => $this->scheduler->id, 'update_date_modified' => false, 'date_modified' => TimeDate::getInstance()->getNow()->modify("-10 days")->asDB())); $oldestjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE, "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id, "scheduler_id" => $this->scheduler->id, 'update_date_modified' => false, 'date_modified' => TimeDate::getInstance()->getNow()->modify("-100 days")->asDb())); $this->assertNotEmpty($newjob->id); $this->assertNotEmpty($oldjob->id); $this->assertNotEmpty($oldestjob->id); $cleanjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_RUNNING, "target" => "function::cleanJobQueue", "assigned_user_id" => $GLOBALS['current_user']->id, "scheduler_id" => $this->scheduler->id)); $cleanjob->runJob(); // new job should be still there $job = new SchedulersJob(); $job->retrieve($newjob->id); $this->assertEquals($newjob->id, $job->id); // old job should be deleted $job = new SchedulersJob(); $job->retrieve($oldjob->id); $this->assertEmpty($job->id); $job->retrieve($oldjob->id, true, false); $this->assertEquals($oldjob->id, $job->id); // oldest job should be purged $count = $this->db->getOne("SELECT count(*) from {$job->table_name} WHERE id='{$oldestjob->id}'"); $this->assertEquals(0, $count); }
/** * Fetch the next job in the queue and mark it running * @param string $clientID ID of the client requesting the job * @return SugarJob */ public function nextJob($clientID) { $now = $this->db->now(); $queued = SchedulersJob::JOB_STATUS_QUEUED; $try = $this->jobTries; while ($try--) { // TODO: tranaction start? $id = $this->db->getOne("SELECT id FROM {$this->job_queue_table} WHERE execute_time <= {$now} AND status = '{$queued}' ORDER BY date_entered ASC"); if (empty($id)) { return null; } $job = new SchedulersJob(); $job->retrieve($id); if (empty($job->id)) { return null; } $job->status = SchedulersJob::JOB_STATUS_RUNNING; $job->client = $clientID; $client = $this->db->quote($clientID); // using direct query here to be able to fetch affected count // if count is 0 this means somebody changed the job status and we have to try again $res = $this->db->query("UPDATE {$this->job_queue_table} SET status='{$job->status}', date_modified={$now}, client='{$client}' WHERE id='{$job->id}' AND status='{$queued}'"); if ($this->db->getAffectedRowCount($res) == 0) { // somebody stole our job, try again continue; } else { // to update dates & possible hooks $job->save(); break; } // TODO: commit/check? } return $job; }
/** * @param $data * @return bool */ public function run($data) { global $current_user; global $current_language; global $locale; $this->job->runnable_ran = true; $this->job->runnable_data = $data; $report_schedule_id = $data; require_once 'modules/Reports/schedule/ReportSchedule.php'; $reportSchedule = new ReportSchedule(); $scheduleInfo = $reportSchedule->getInfo($report_schedule_id); $GLOBALS["log"]->debug("-----> in Reports foreach() loop"); $savedReport = BeanFactory::getBean('Reports', $scheduleInfo['report_id']); $GLOBALS["log"]->debug("-----> Generating Reporter"); require_once 'modules/Reports/Report.php'; $reporter = new Report(from_html($savedReport->content)); $reporter->is_saved_report = true; $reporter->saved_report = $savedReport; $reporter->saved_report_id = $savedReport->id; $mod_strings = return_module_language($current_language, 'Reports'); // prevent invalid report from being processed if (!$reporter->is_definition_valid()) { $invalidFields = $reporter->get_invalid_fields(); $args = array($scheduleInfo['report_id'], implode(', ', $invalidFields)); $message = string_format($mod_strings['ERR_REPORT_INVALID'], $args); $GLOBALS["log"]->fatal("-----> {$message}"); $reportOwner = BeanFactory::retrieveBean('Users', $savedReport->assigned_user_id); if ($reportOwner) { require_once 'modules/Reports/utils.php'; $reportsUtils = new ReportsUtilities(); try { $reportsUtils->sendNotificationOfInvalidReport($reportOwner, $message); } catch (MailerException $me) { //@todo consider logging the error at the very least } } $this->job->failJob('Report field definition is invalid'); return false; } else { $GLOBALS["log"]->debug("-----> Reporter settings attributes"); $reporter->layout_manager->setAttribute("no_sort", 1); $GLOBALS["log"]->debug("-----> Reporter Handling PDF output"); require_once 'modules/Reports/templates/templates_tcpdf.php'; $reportFilename = template_handle_pdf($reporter, false); // get the recipient's data... // first get all email addresses known for this recipient $recipientEmailAddresses = array($current_user->email1, $current_user->email2); $recipientEmailAddresses = array_filter($recipientEmailAddresses); // then retrieve first non-empty email address $recipientEmailAddress = array_shift($recipientEmailAddresses); // get the recipient name that accompanies the email address $recipientName = $locale->formatName($current_user); $result = false; try { $GLOBALS["log"]->debug("-----> Generating Mailer"); $mailer = MailerFactory::getSystemDefaultMailer(); // set the subject of the email $subject = empty($savedReport->name) ? "Report" : $savedReport->name; $mailer->setSubject($subject); // add the recipient $mailer->addRecipientsTo(new EmailIdentity($recipientEmailAddress, $recipientName)); // attach the report, using the subject as the name of the attachment $charsToRemove = array("\r", "\n"); // remove these characters from the attachment name $attachmentName = str_replace($charsToRemove, "", $subject); // replace spaces with the underscores $attachmentName = str_replace(" ", "_", "{$attachmentName}.pdf"); $attachment = new Attachment($reportFilename, $attachmentName, Encoding::Base64, "application/pdf"); $mailer->addAttachment($attachment); // set the body of the email $body = $mod_strings["LBL_HELLO"]; if ($recipientName != "") { $body .= " {$recipientName}"; } $body .= ",\n\n" . $mod_strings["LBL_SCHEDULED_REPORT_MSG_INTRO"] . $savedReport->date_entered . $mod_strings["LBL_SCHEDULED_REPORT_MSG_BODY1"] . $savedReport->name . $mod_strings["LBL_SCHEDULED_REPORT_MSG_BODY2"]; $textOnly = EmailFormatter::isTextOnly($body); if ($textOnly) { $mailer->setTextBody($body); } else { $textBody = strip_tags(br2nl($body)); // need to create the plain-text part $mailer->setTextBody($textBody); $mailer->setHtmlBody($body); } $GLOBALS["log"]->debug("-----> Sending PDF via Email to [ {$recipientEmailAddress} ]"); $mailer->send(); $result = true; $GLOBALS["log"]->debug("-----> Send successful"); $reportSchedule->update_next_run_time($report_schedule_id, $scheduleInfo["next_run"], $scheduleInfo["time_interval"]); } catch (MailerException $me) { switch ($me->getCode()) { case MailerException::InvalidEmailAddress: $GLOBALS["log"]->info("No email address for {$recipientName}"); break; default: $GLOBALS["log"]->fatal("Mail error: " . $me->getMessage()); break; } } $GLOBALS["log"]->debug("-----> Removing temporary PDF file"); unlink($reportFilename); if ($result) { $this->job->succeedJob(); } return $result; } }
if (substr($sapi_type, 0, 3) != 'cli') { sugar_die("run_job.php is CLI only."); } if ($argc < 3 || empty($argv[1]) || empty($argv[2])) { sugar_die("run_job.php requires job ID and client ID as parameters."); } if (empty($current_language)) { $current_language = $sugar_config['default_language']; } $app_list_strings = return_app_list_strings_language($current_language); $app_strings = return_application_language($current_language); $current_user = new User(); $current_user->getSystemUser(); Log::debug('Starting job {$argv[1]} execution as ${argv[2]}'); require_once 'modules/SchedulersJobs/SchedulersJob.php'; $result = SchedulersJob::runJobId($argv[1], $argv[2]); if (is_string($result)) { // something wrong happened echo $result; echo "\n"; $result = false; } sugar_cleanup(false); // some jobs have annoying habit of calling sugar_cleanup(), and it can be called only once // but job results can be written to DB after job is finished, so we have to disconnect here again // just in case we couldn't call cleanup if (class_exists('DBManagerFactory')) { $db = DBManagerFactory::getInstance(); $db->disconnect(); } exit($result ? 0 : 1);
public function testServerFailureWithError() { $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->scheduler_id = 'unittest'; $job->execute_time = TimeDate::getInstance()->nowDb(); $job->name = "Unit test Job"; $job->target = "function::CronTest::cronJobFunction"; $job->assigned_user_id = $GLOBALS['current_user']->id; $job->save(); $jobid = $job->id; $this->client->return = 'This is not the server you are looking for'; $this->jq->min_interval = 0; // disable throttle $this->jq->disable_schedulers = true; $this->jq->runCycle(); $this->assertFalse($this->jq->runOk()); $job = new SchedulersJob(); $job->retrieve($jobid); $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution"); $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status"); $this->assertContains('This is not the server you are looking for', $job->message, "Wrong message"); }
/** * executes Scheduled job */ function fire() { if (empty($this->job)) { // only execute when valid $GLOBALS['log']->fatal('Scheduler tried to fire an empty job!!'); return false; } $exJob = explode('::', $this->job); if (is_array($exJob)) { // instantiate a new SchedulersJob object and prep it $trackerManager = TrackerManager::getInstance(); $trackerManager->pause(); $job = new SchedulersJob(); $job->scheduler_id = $this->id; $job->scheduler =& $this; $job->execute_time = $job->handleDateFormat('now'); $jobId = $job->save(); $trackerManager->unPause(); $job->retrieve($jobId); if ($exJob[0] == 'function') { $GLOBALS['log']->debug('----->Scheduler found a job of type FUNCTION'); require_once 'modules/Schedulers/_AddJobsHere.php'; $job->setJobFlag(1); $func = $exJob[1]; $GLOBALS['log']->debug('----->SchedulersJob firing ' . $func); $res = call_user_func($func); if ($res) { $job->setJobFlag(2); $job->finishJob(); return true; } else { $job->setJobFlag(3); return false; } } elseif ($exJob[0] == 'url') { if (function_exists('curl_init')) { $GLOBALS['log']->debug('----->SchedulersJob found a job of type URL'); $job->setJobFlag(1); $GLOBALS['log']->debug('----->SchedulersJob firing URL job: ' . $exJob[1]); if ($job->fireUrl($exJob[1])) { $job->setJobFlag(2); $job->finishJob(); return true; } else { $job->setJobFlag(3); return false; } } else { $job->setJobFlag(4); return false; } } } return false; }
/** * testSchedulersJobHandleDateFormatWithOtherTime * */ public function testSchedulersJobHandleDateFormatWithOtherTime() { global $current_user; $job = new SchedulersJob(false); $job->user = $current_user; $this->assertRegExp('/^\\d{4}\\-\\d{2}\\-\\d{2}\\s\\d{1,2}\\:\\d{2}\\:\\d{2}$/', $job->handleDateFormat('+7 days')); $this->assertRegExp('/^\\d{4}\\-\\d{2}\\-\\d{2}\\s\\d{1,2}\\:\\d{2}\\:\\d{2}$/', $job->handleDateFormat('+7 days', $current_user, false)); $this->assertRegExp('/^\\d{1,2}\\/\\d{1,2}\\/\\d{4}\\s\\d{1,2}\\:\\d{2}$/', $job->handleDateFormat('+7 days', $current_user, true)); }
public function testJobsCleanupReschedule() { $this->scheduler->job_interval = "*::*::*::*::*"; $this->scheduler->job = "test::test"; $this->scheduler->status = "Active"; $this->scheduler->new_with_id = true; $this->scheduler->save(); $job = new SchedulersJob(); $job->update_date_modified = false; $job->status = SchedulersJob::JOB_STATUS_RUNNING; $job->scheduler_id = $this->scheduler->id; $job->execute_time = $GLOBALS['timedate']->nowDb(); $job->date_entered = '2010-01-01 12:00:00'; $job->date_modified = '2010-01-01 12:00:00'; $job->name = "Unit test Job 1"; $job->target = "test::test"; $job->assigned_user_id = $GLOBALS['current_user']->id; $job->save(); $jobid = $job->id; // try queue run with old job stuck $queue = new MockSchedulerQueue(); $this->scheduler->checkPendingJobs($queue); $ourjob = null; foreach ($queue->jobs as $job) { if ($job->scheduler_id == $this->scheduler->id) { $ourjob = $job; break; } } $this->assertEmpty($ourjob, "Duplicate job found"); // now cleanup the job $queue->cleanup(); $job = new SchedulersJob(); $job->retrieve($jobid); $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status"); $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution"); // now try again - should schedule now $queue = new MockSchedulerQueue(); $this->scheduler->checkPendingJobs($queue); $ourjob = null; foreach ($queue->jobs as $job) { if ($job->scheduler_id == $this->scheduler->id) { $ourjob = $job; break; } } $this->assertNotEmpty($ourjob, "Could not find our job in the queue"); }
/** * This function takes a look at the schedulers_times table and pulls the * jobs to be run at this moment in time (anything not run and with a run * time or earlier than right now) * @return $successful Boolean flag whether a job(s) is found */ function checkPendingJobs() { global $sugar_config; global $current_user; $GLOBALS['log']->debug(''); $GLOBALS['log']->debug('----->Scheduler checking for qualified jobs to run.'); if (empty($this->db)) { $this->db =& PearDatabase::getInstance(); } $fireTimeMinus = gmdate('Y-m-d H:i:s', strtotime('now -1 min')); $fireTimePlus = gmdate('Y-m-d H:i:s', strtotime('now +1 min')); // collapse list of schedulers where "catch_up" is 0 and status is "ready" (not "in progress, completed, etc."); if ($sugar_config['dbconfig']['db_type'] == 'oci8') { } else { $q = 'UPDATE schedulers_times st LEFT JOIN schedulers s ON st.scheduler_id = s.id SET st.status = \'not run\' WHERE st.execute_time < ' . db_convert('\'' . $fireTimeMinus . '\'', 'datetime') . ' AND st.status = \'ready\' AND s.catch_up = 0'; } $this->db->query($q); $q = 'SELECT DISTINCT st.id, st.scheduler_id, st.status, s.name, s.job FROM schedulers_times st LEFT JOIN schedulers s ON st.scheduler_id = s.id WHERE st.execute_time < ' . db_convert('\'' . $fireTimePlus . '\'', 'datetime') . ' AND st.deleted=0 AND s.deleted=0 AND st.status=\'ready\' AND s.status=\'Active\' ORDER BY s.name'; $r = $this->db->query($q); $count = 0; if ($sugar_config['dbconfig']['db_type'] == 'mysql') { $loopCount = $this->db->getRowCount($r); $GLOBALS['log']->debug('----->Scheduler has ' . $loopCount . ' jobs to fire.'); } while ($a = $this->db->fetchByAssoc($r)) { require_once 'modules/SchedulersJobs/SchedulersJob.php'; $job = new SchedulersJob(); $paramJob = $a['scheduler_id']; $job->fire($sugar_config['site_url'] . '/schedulers.php?type=job&job_id=' . $paramJob . '&record=' . $a['id']); $count++; } if ($count < 1) { $GLOBALS['log']->debug('----->Scheduler has found 0 Jobs to fire'); } }
public function testJobsCleanup() { // job 1 - oldest, should be executed $job = new SchedulersJob(); $job->update_date_modified = false; $job->status = SchedulersJob::JOB_STATUS_RUNNING; $job->scheduler_id = 'unittest'; $job->execute_time = TimeDate::getInstance()->nowDb(); $job->date_entered = '2010-01-01 12:00:00'; $job->date_modified = '2010-01-01 12:00:00'; $job->name = "Unit test Job 1"; $job->target = "function::CronTest::cronJobFunction"; $job->assigned_user_id = $GLOBALS['current_user']->id; $job->save(); $jobid1 = $job->id; $this->jq->min_interval = 0; // disable throttle $this->jq->disable_schedulers = true; $this->jq->runCycle(); $this->assertFalse(self::$jobCalled, "Job was called"); $this->assertFalse($this->jq->runOk(), "Wrong OK flag"); $job = new SchedulersJob(); $job->retrieve($jobid1); $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status"); $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution"); $this->assertEmpty(session_id(), "Session not destroyed"); }
public function testGetNextJob() { // should get only jobs with status QUEUED, in date_entered order, and mark them as running // Clean up the queue $GLOBALS['db']->query("DELETE FROM job_queue WHERE status='" . SchedulersJob::JOB_STATUS_QUEUED . "'"); $job = $this->jq->nextJob("unit test"); $this->assertNull($job, "Extra job found"); // older job $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->scheduler_id = 'unittest'; $job->date_entered = '2010-01-01 12:00:00'; $job->name = "Old Job"; $job->target = "test::test"; $job->save(); $jobid1 = $job->id; // another job, later date $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->scheduler_id = 'unittest'; $job->date_entered = '2012-01-01 12:00:00'; $job->name = "Newer Job"; $job->target = "test::test"; $job->save(); $jobid2 = $job->id; // job with execute date in the future $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_QUEUED; $job->scheduler_id = 'unittest'; $job->execute_time = $GLOBALS['timedate']->getNow()->modify("+3 days")->asDb(); $job->date_entered = '2010-01-01 12:00:00'; $job->name = "Future Job"; $job->target = "test::test"; $job->save(); $jobid3 = $job->id; //running job $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_RUNNING; $job->scheduler_id = 'unittest'; $job->date_entered = '2010-01-01 12:00:00'; $job->name = "Running Job"; $job->target = "test::test"; $job->save(); $jobid4 = $job->id; // done job $job = new SchedulersJob(); $job->status = SchedulersJob::JOB_STATUS_DONE; $job->scheduler_id = 'unittest'; $job->date_entered = '2010-01-01 12:00:00'; $job->name = "Done Job"; $job->target = "test::test"; $job->save(); $jobid5 = $job->id; // get the first one $job = $this->jq->nextJob("unit test"); $this->assertEquals($jobid1, $job->id, "Wrong job fetched"); $this->assertEquals(SchedulersJob::JOB_STATUS_RUNNING, $job->status, "Wrong status"); $this->assertEquals("unit test", $job->client, "Wrong client"); // check that DB record matches $job = new SchedulersJob(); $job->retrieve($jobid1); $this->assertEquals(SchedulersJob::JOB_STATUS_RUNNING, $job->status, "Wrong status"); $this->assertEquals("unit test", $job->client, "Wrong client"); // get the second one $job = $this->jq->nextJob("unit test"); $this->assertEquals($jobid2, $job->id, "Wrong job fetched"); $this->assertEquals(SchedulersJob::JOB_STATUS_RUNNING, $job->status, "Wrong status"); $this->assertEquals("unit test", $job->client, "Wrong client"); // try to get the third one, should get null $job = $this->jq->nextJob("unit test"); $this->assertNull($job, "Extra job found"); }
/** * Run job from queue * @param string $session * @param string $jobid * @param string $clientid */ public function job_queue_run($session, $jobid, $clientid) { $GLOBALS['log']->info('Begin: SugarWebServiceImpl->job_queue_run'); $error = new SoapError(); if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', 'read', 'no_access', $error)) { $GLOBALS['log']->info('End: SugarWebServiceImpl->job_queue_run denied.'); return; } $GLOBALS['log']->debug('Starting job $jobid execution as $clientid'); require_once 'modules/SchedulersJobs/SchedulersJob.php'; $result = SchedulersJob::runJobId($jobid, $clientid); $GLOBALS['log']->info('End: SugarWebServiceImpl->job_queue_run'); if ($result === true) { return array("results" => true); } else { return array("results" => false, "message" => $result); } }
/** * This function takes a look at the schedulers_times table and pulls the * jobs to be run at this moment in time (anything not run and with a run * time or earlier than right now) * @return $successful Boolean flag whether a job(s) is found */ function checkPendingJobs() { global $sugar_config; global $timedate; $GLOBALS['log']->debug(''); $GLOBALS['log']->debug('----->Scheduler checking for qualified jobs to run.'); if (empty($this->db)) { $this->db = DBManagerFactory::getInstance(); } $fireTimeMinus = $timedate->asDb($timedate->getNow()->get('-1 minute')); $fireTimePlus = $timedate->asDb($timedate->getNow()->get('+1 minute')); // collapse list of schedulers where "catch_up" is 0 and status is "ready" (not "in progress, completed, etc."); $q = 'UPDATE schedulers_times st SET st.status = \'not run\' WHERE st.execute_time < ' . $this->db->convert($this->db->quoted($fireTimeMinus), 'datetime') . ' AND st.status = \'ready\' AND st.scheduler_id IN (SELECT s.id FROM schedulers s WHERE st.scheduler_id = s.id AND s.catch_up = 0)'; $this->db->query($q); $q = 'SELECT DISTINCT st.id, st.scheduler_id, st.status, s.name, s.job FROM schedulers_times st LEFT JOIN schedulers s ON st.scheduler_id = s.id WHERE st.execute_time < ' . $this->db->convert($this->db->quoted($fireTimeMinus), 'datetime') . ' AND st.deleted=0 AND s.deleted=0 AND st.status=\'ready\' AND s.status=\'Active\' ORDER BY s.name'; $r = $this->db->query($q); $count = 0; while ($a = $this->db->fetchByAssoc($r)) { $job = new SchedulersJob(); $paramJob = $a['scheduler_id']; $job->fire($sugar_config['site_url'] . '/index.php?entryPoint=schedulers&type=job&job_id=' . $paramJob . '&record=' . $a['id']); $count++; } if ($count < 1) { $GLOBALS['log']->debug('----->Scheduler has found 0 Jobs to fire'); } }