function testResolveAsyncJobClearMutexWhenNotInWaitAsync()
 {
     // create a queuestore
     $q = new JQStore_Array();
     $mJob = $q->enqueue(new SampleAsyncJob(NULL));
     $mJob->markJobStarted();
     $mJob->markJobFailed();
     $this->assertEquals(JQManagedJob::STATUS_FAILED, $mJob->getStatus());
     try {
         JQManagedJob::resolveWaitAsyncJob($q, $mJob->getJobId(), NULL);
     } catch (JQManagedJob_InvalidStateException $e) {
         $this->assertEquals($mJob, $q->getWithMutex($mJob->getJobId()));
         return;
     }
     $this->fail('should never get here');
 }
print <<<EXPLAIN
***********************************************************************************************************
  This test makes sure that a fatal error during job execution will result in the job being marked failed.
  This exercises our shutdown error detection.

  This test works if you see output indicating:
    - a job starts running
    - then a fatal error
    - finally "Status change: running => failed"
***********************************************************************************************************


EXPLAIN;
class SampleFatalJob extends SampleLoggingJob
{
    function run(JQManagedJob $mJob)
    {
        // causes a FATAL error
        $foo->bar();
    }
}
// run a job that will FATAL
$q = new JQStore_Array();
$goodJob = $q->enqueue(new SampleFatalJob());
if ($q->count('test') !== 1) {
    throw new Exception("assert failed");
}
SampleJobCounter::reset();
// Start a worker to run the job.
$w = new JQWorker($q, array('queueName' => 'test', 'exitIfNoJobs' => true, 'verbose' => true, 'enableJitter' => false));
$w->start();
Exemple #3
0
 function testJobsAutoRetryOnFailure()
 {
     // create a queuestore
     $maxAttempts = 5;
     $q = new JQStore_Array();
     $mJob = $q->enqueue(new SampleFailJob(array('maxAttempts' => $maxAttempts)));
     // Start a worker to run the jobs.
     $w = new JQWorker($q, array('queueName' => 'test', 'exitIfNoJobs' => true, 'silent' => true, 'enableJitter' => false));
     $w->start();
     $this->assertEquals(0, $q->count('test', 'queued'));
     $this->assertEquals(1, $q->count('test', 'failed'));
     $this->assertEquals($maxAttempts, $mJob->getAttemptNumber());
 }
<?php

/**
 * This script verifies that a job that generates a CATCHABLE FATAL ERROR will gracefully fail the job...
 */
require_once dirname(__FILE__) . '/../TestCommon.php';
print <<<EXPLAIN
***********************************************************************************************************
  This test makes sure that a fatal error AFTER a job runs successfully doesn't try to fail the
  already completed job.

  This test works if you see output indicating:
    - a successful job run
    - then a fatal error
    - no subsequent job status changes
***********************************************************************************************************


EXPLAIN;
// run a job that will FATAL
$q = new JQStore_Array();
$goodJob = $q->enqueue(new SampleLoggingJob());
if ($q->count('test') !== 1) {
    throw new Exception("assert failed");
}
SampleJobCounter::reset();
// Start a worker to run the job.
$w = new JQWorker($q, array('queueName' => 'test', 'exitIfNoJobs' => true, 'silent' => true, 'enableJitter' => false));
$w->start();
// trigger a fatal error; shouldn't fail our job, though as we should be out-of-scope.
$foo->bar();
<?php

// we have the job in a separate file as a proof-of-concept that the declare(ticks=1) works in this situation.
require_once 'jq-test-signal-job.php';
// to have JQJobs be able to gracefully handle SIGKILL (or other *immediate termination* signals) the declare() must be at this level.
declare (ticks=1);
// The idea of these signal tests is to test the time between the SIGTERM and the SIGKILL;
// THERE are 2 cases to test:
// 1. Job finishes in time window between SIGTERM and SIGKILL, expect JOB COMPLETION and GRACEFUL SHUTDOWN
//    The way this test works is to run a job that takes 3 seconds; send TERM after 1s and KILL after 7
// 2. Job doesn't finish before SIGKILL; expect JOB FAILURE (retry) AND NON-GRACEFUL SHUTDOWN
//    The way this test works is to run a job that takes 10 seconds; send TERM after 1s and KILL after 7
if (!isset($argv[1])) {
    die("Pass one argument with integer number of seconds the job under signal test should take.");
}
$params = json_decode($argv[1], true);
print "Job Runtime: {$params['jobRunTime']}\n";
print "System TERM-to-KILL window: {$params['systemTermToKillWindow']}\n";
$q = new JQStore_Array();
$q->enqueue(new UninterruptibleJob($params['jobRunTime']));
$q->enqueue(new UninterruptibleJob());
// this 2nd job is there so that in test #1, that the worker has more work to do but gracefully exits anyway due to receiving the signal
$w = new JQWorker($q, array('verbose' => true, 'enableJitter' => false, 'gracefulShutdownTimeout' => $params['systemTermToKillWindow']));
$w->start();