Skip to content

Commit

Permalink
API Add optional time limit
Browse files Browse the repository at this point in the history
  • Loading branch information
Damian Mooyman committed May 21, 2015
1 parent ba94a35 commit 609b55e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ set the notification email address in your config as below:
Email:
queued_job_admin_email: [email protected]

## Memory limit configuration
## Performance configuration

By default this task will run until either 128mb or the limit specified by php_ini('memory_limit') is reached.

Expand All @@ -134,6 +134,16 @@ You can adjust this with the below config change
memory_limit: 256m


You can also enforce a time limit for each queue, after which the task will attempt a restart to release all
resources. By default this is disabled, so you must specify this in your project as below:


:::yaml
# Force limit to 10 minutes
QueuedJobsService:
time_limit: 600


## Indexes

ALTER TABLE `QueuedJobDescriptor` ADD INDEX ( `JobStatus` , `JobType` )
Expand Down
63 changes: 61 additions & 2 deletions code/services/QueuedJobService.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ class QueuedJobService {
* @config
*/
private static $memory_limit = 134217728;

/**
* Optional time limit (in seconds) to run the service before restarting to release resources.
*
* Defaults to no limit.
*
* @var int
* @config
*/
private static $time_limit = 0;

/**
* Timestamp (in seconds) when the queue was started
*
* @var int
*/
protected $startedAt = 0;

/**
* Should "immediate" jobs be managed using the shutdown function?
Expand Down Expand Up @@ -529,6 +546,16 @@ public function runJob($jobId) {
$jobDescriptor->JobStatus = QueuedJob::STATUS_WAIT;
$broken = true;
}

// Also check if we are running too long
if($this->hasPassedTimeLimit()) {
$job->addMessage(_t(
'QueuedJobs.TIME_LIMIT',
'Queue has passed time limit and will restart before continuing'
));
$jobDescriptor->JobStatus = QueuedJob::STATUS_WAIT;
$broken = true;
}
}

if ($jobDescriptor) {
Expand Down Expand Up @@ -579,6 +606,35 @@ public function runJob($jobId) {
return !$broken;
}

/**
* Start timer
*/
protected function markStarted() {
if($this->startedAt) {
$this->startedAt = SS_Datetime::now()->Format('U');
}
}

/**
* Is execution time too long?
*
* @return bool True if the script has passed the configured time_limit
*/
protected function hasPassedTimeLimit() {
// Ensure a limit exists
$limit = Config::inst()->get(__CLASS__, 'time_limit');
if(!$limit) {
return false;
}

// Ensure started date is set
$this->markStarted();

// Check duration
$now = SS_Datetime::now()->Format('U');
return $now > $this->startedAt + $limit;
}

/**
* Is memory usage too high?
*
Expand Down Expand Up @@ -700,10 +756,13 @@ public function getJobListFilter($type = null, $includeUpUntil = 0) {
/**
* Process all jobs from a given queue
*
* @param string $name
* The job queue to completely process
* @param string $name The job queue to completely process
*/
public function processJobQueue($name) {
// Start timer to measure lifetime
$this->markStarted();

// Begin main loop
do {
if (class_exists('Subsite')) {
// clear subsite back to default to prevent any subsite changes from leaking to
Expand Down

0 comments on commit 609b55e

Please sign in to comment.