I'm having a bit of trouble getting a job to run reliably without getting stuck as "Paused" or "Initializing". It does however run correctly sometimes...
I found the examples (https://github.com/silverstripe-australia/silverstripe-queuedjobs/tree/master/code/jobs) to be a little confusing as they don't follow the same process in terms of where things are set. For example the DeleteObject example sets the currentStep to 0 in the constructor where the other examples don't...
My job isn't complicated but would love some help to clean it up if possible.
<?php
/**
* Process all TwitterObjects that are ready to be built. All I'm doing is creating a short URL from a API services
* and writing the value into the field in the each TwitterObject. On completing the job, if their are TwitterObjects
* now ready to send to twitter, create that job. I reschedule this job to run every 15 minutes or so.
*
* Class BuildTwitterMessageJob
*
* @package: twitter-notify
*/
class BuildTwitterMessageJob extends AbstractQueuedJob implements QueuedJob
{
private $google;
private $twitterObject;
/**
* TwitterObject is a standard Silverstripe Object
*/
public function __construct()
{
$this->twitterObject = TwitterObject::getToBuild();
$this->currentStep = 0;
$this->totalSteps = count($this->twitterObject);
// Empty job, no point in going further
if ($this->totalSteps == 0) {
$this->jobComplete();
}
}
public function getJobType()
{
return QueuedJob::QUEUED;
}
public function getTitle()
{
return "Build tweets";
}
/**
* Only allow one job of this type
*
* @return string
*/
public function getSignature()
{
return md5(get_class($this));
}
/**
* Create a google object which handles the URL shortening
*/
public function setup()
{
parent::setup();
$baseUrl = SiteConfig::current_site_config()->GoogleApiBaseUrl;
$api = SiteConfig::current_site_config()->GoogleShortURLServerAPI;
$this->google = new GoogleShortUrl($baseUrl, $api);
}
/**
* Merge the short URL with the body of the message on each TwitterObject. Update both the state of the object
* and the message as appropriate.
*/
public function process()
{
$remainingChildren = $this->twitterObject;
if (!count($remainingChildren)) {
$this->jobComplete();
}
$tweet = array_shift($remainingChildren);
// +++ Actual process
$tweet->BuildStatus = TwitterConst::FLAG_PROCESSING;
$tweet->write();
// Update body of the message with short URL
$tweet->Link = $this->google->getShortUrl($tweet->Link);
$tweet->Message = $tweet->Message . " " . $tweet->Link;
// Flag as complete
$tweet->BuildStatus = TwitterConst::FLAG_DONE;
$tweet->write();
// Tidy up
$this->twitterObject = $remainingChildren;
$this->currentStep++;
if (!count($remainingChildren)) {
$this->jobComplete();
}
}
/**
* @return bool
*/
public function jobComplete()
{
$this->addMessage('Complete');
$this->createSendJob();
$this->reschedule();
$this->isComplete = true;
return;
}
/**
* Create a new job to send the built tweets.
*/
private function createSendJob()
{
if (TwitterObject::getToSend()) {
singleton('QueuedJobService')->queueJob(new SendTwitterMessageJob(TwitterObject::getToSend(), time()));
}
}
/**
* Rerun this task every minute from the time it is created (Google can handle a bit of spam)
*/
private function reschedule()
{
$run_rate = floor(SiteConfig::current_site_config()->TwitterSendRate * 60);
singleton('QueuedJobService')->queueJob(new BuildTwitterMessageJob(TwitterObject::getToBuild()), date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s', time())) + $run_rate));
}
}