Skip to content

Add base Job class #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Resque\Resque::enqueue('default', 'My_Job', $args);
Each job should be in its own class, and include a `perform` method.

```php
class My_Job
class My_Job extends \Resque\Job\Job
{
public function perform()
{
Expand All @@ -132,9 +132,9 @@ defined, it will be called before the `perform` method is run. The `tearDown`
method, if defined, will be called after the job finishes.

```php
class My_Job
class My_Job extends \Resque\Job\Job
{
public function setUp()
public function setUp(): void
{
// ... Set up environment for this job
}
Expand All @@ -144,7 +144,7 @@ class My_Job
// .. Run job
}

public function tearDown()
public function tearDown(): void
{
// ... Remove environment for this job
}
Expand Down
10 changes: 2 additions & 8 deletions lib/Job/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,17 @@ class Factory implements FactoryInterface
* @param $className
* @param array $args
* @param $queue
* @return \Resque\Job\JobInterface
* @return \Resque\Job\Job
* @throws \Resque\Exceptions\ResqueException
*/
public function create($className, $args, $queue)
public function create(string $className, array $args, string $queue): Job
{
if (!class_exists($className)) {
throw new ResqueException(
'Could not find job class ' . $className . '.'
);
}

if (!method_exists($className, 'perform')) {
throw new ResqueException(
'Job class ' . $className . ' does not contain a perform method.'
);
}

$instance = new $className();
$instance->args = $args;
$instance->queue = $queue;
Expand Down
4 changes: 2 additions & 2 deletions lib/Job/FactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface FactoryInterface
* @param $className
* @param array $args
* @param $queue
* @return \Resque\Job\JobInterface
* @return \Resque\Job\Job
*/
public function create($className, $args, $queue);
public function create(string $className, array $args, string $queue): Job;
}
60 changes: 60 additions & 0 deletions lib/Job/Job.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Resque\Job;

use Resque\JobHandler;

/**
* Base Resque Job class.
*
* @package Resque\Job
* @author Heinz Wiesinger <[email protected]>
* @license http://www.opensource.org/licenses/mit-license.php
*/
abstract class Job
{
/**
* Job arguments
* @var array
*/
public $args;

/**
* Associated JobHandler instance
* @var JobHandler
*/
public $job;

/**
* Name of the queue the job was in
* @var string
*/
public $queue;

/**
* (Optional) Job setup
*
* @return void
*/
public function setUp(): void
{
// no-op
}

/**
* (Optional) Job teardown
*
* @return void
*/
public function tearDown(): void
{
// no-op
}

/**
* Main method of the Job
*
* @return mixed|void
*/
abstract public function perform();
}
11 changes: 0 additions & 11 deletions lib/Job/JobInterface.php

This file was deleted.

34 changes: 12 additions & 22 deletions lib/JobHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace Resque;

use InvalidArgumentException;
use Resque\Job\PID;
use Resque\Job\Status;
use Resque\Exceptions\DoNotPerformException;
use Resque\Job\FactoryInterface;
use Resque\Job\Factory;
use Resque\Job\Job;
use Error;

/**
Expand Down Expand Up @@ -50,7 +50,7 @@ class JobHandler
public $endTime;

/**
* @var object|\Resque\Job\JobInterface Instance of the class performing work for this job.
* @var Job Instance of the class performing work for this job.
*/
private $instance;

Expand Down Expand Up @@ -83,19 +83,13 @@ public function __construct($queue, $payload)
* @param string $prefix The prefix needs to be set for the status key
*
* @return string
* @throws \InvalidArgumentException
*/
public static function create($queue, $class, $args = null, $monitor = false, $id = null, $prefix = "")
public static function create($queue, $class, array $args = [], $monitor = false, $id = null, $prefix = "")
{
if (is_null($id)) {
$id = Resque::generateJobId();
}

if ($args !== null && !is_array($args)) {
throw new InvalidArgumentException(
'Supplied $args must be an array.'
);
}
Resque::push($queue, array(
'class' => $class,
'args' => array($args),
Expand Down Expand Up @@ -183,7 +177,7 @@ public function getStatus()
*
* @return array Array of arguments.
*/
public function getArguments()
public function getArguments(): array
{
if (!isset($this->payload['args'])) {
return array();
Expand All @@ -194,10 +188,10 @@ public function getArguments()

/**
* Get the instantiated object for this job that will be performing work.
* @return \Resque\Job\JobInterface Instance of the object that this job belongs to.
* @return \Resque\Job\Job Instance of the object that this job belongs to.
* @throws \Resque\Exceptions\ResqueException
*/
public function getInstance()
public function getInstance(): Job
{
if (!is_null($this->instance)) {
return $this->instance;
Expand All @@ -212,9 +206,8 @@ public function getInstance()
* Actually execute a job by calling the perform method on the class
* associated with the job with the supplied arguments.
*
* @return bool
* @throws Resque\Exceptions\ResqueException When the job's class could not be found
* or it does not contain a perform method.
* @return mixed
* @throws Resque\Exceptions\ResqueException When the job's class could not be found.
*/
public function perform()
{
Expand All @@ -225,15 +218,12 @@ public function perform()
$this->startTime = microtime(true);

$instance = $this->getInstance();
if (is_callable([$instance, 'setUp'])) {
$instance->setUp();
}

$instance->setUp();

$result = $instance->perform();

if (is_callable([$instance, 'tearDown'])) {
$instance->tearDown();
}
$instance->tearDown();

$this->endTime = microtime(true);

Expand Down Expand Up @@ -343,7 +333,7 @@ public function setJobFactory(FactoryInterface $jobFactory)
/**
* @return Resque\Job\FactoryInterface
*/
public function getJobFactory()
public function getJobFactory(): FactoryInterface
{
if ($this->jobFactory === null) {
$this->jobFactory = new Factory();
Expand Down
2 changes: 1 addition & 1 deletion lib/Resque.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public static function size($queue)
*
* @return string|boolean Job ID when the job was created, false if creation was cancelled due to beforeEnqueue
*/
public static function enqueue($queue, $class, $args = null, $trackStatus = false, $prefix = "")
public static function enqueue($queue, $class, array $args = [], $trackStatus = false, $prefix = "")
{
$id = Resque::generateJobId();
$hookParams = array(
Expand Down
31 changes: 11 additions & 20 deletions test/Resque/Tests/JobHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use \Resque\Redis;
use \Resque\JobHandler;
use \Resque\Stat;
use \Resque\Job\JobInterface;
use \Resque\Job\Job;
use \Resque\Job\FactoryInterface;
use \Test_Job_With_SetUp;
use \Test_Job_With_TearDown;
Expand Down Expand Up @@ -68,15 +68,6 @@ public function testQeueuedJobCanBeReserved()
$this->assertEquals('Test_Job', $job->payload['class']);
}

public function testObjectArgumentsCannotBePassedToJob()
{
$this->expectException('InvalidArgumentException');

$args = new stdClass();
$args->test = 'somevalue';
Resque::enqueue('jobs', 'Test_Job', $args);
}

public function testQueuedJobReturnsExactSamePassedInArguments()
{
$args = array(
Expand Down Expand Up @@ -168,10 +159,10 @@ public function testJobWithSetUpCallbackFiresSetUp()
{
$payload = array(
'class' => 'Test_Job_With_SetUp',
'args' => array(
'args' => array(array(
'somevar',
'somevar2',
),
)),
);
$job = new JobHandler('jobs', $payload);
$job->perform();
Expand All @@ -183,10 +174,10 @@ public function testJobWithTearDownCallbackFiresTearDown()
{
$payload = array(
'class' => 'Test_Job_With_TearDown',
'args' => array(
'args' => array(array(
'somevar',
'somevar2',
),
)),
);
$job = new JobHandler('jobs', $payload);
$job->perform();
Expand Down Expand Up @@ -410,7 +401,7 @@ public function testUseFactoryToGetJobInstance()
$factory = new Some_Stub_Factory();
$job->setJobFactory($factory);
$instance = $job->getInstance();
$this->assertInstanceOf('Resque\Job\JobInterface', $instance);
$this->assertInstanceOf('Resque\Job\Job', $instance);
}

public function testDoNotUseFactoryToGetInstance()
Expand All @@ -422,11 +413,11 @@ public function testDoNotUseFactoryToGetInstance()
$job = new JobHandler('jobs', $payload);
$factory = $this->getMockBuilder('Resque\Job\FactoryInterface')
->getMock();
$testJob = $this->getMockBuilder('Resque\Job\JobInterface')
$testJob = $this->getMockBuilder('Resque\Job\Job')
->getMock();
$factory->expects(self::never())->method('create')->will(self::returnValue($testJob));
$instance = $job->getInstance();
$this->assertInstanceOf('Resque\Job\JobInterface', $instance);
$this->assertInstanceOf('Resque\Job\Job', $instance);
}

public function testJobStatusIsNullIfIdMissingFromPayload()
Expand Down Expand Up @@ -505,7 +496,7 @@ public function testJobHandlerSetsStartAndEndTimeForFailedJob()
}
}

class Some_Job_Class implements JobInterface
class Some_Job_Class extends Job
{

/**
Expand All @@ -524,9 +515,9 @@ class Some_Stub_Factory implements FactoryInterface
* @param $className
* @param array $args
* @param $queue
* @return Resque\Job\JobInterface
* @return Resque\Job\Job
*/
public function create($className, $args, $queue)
public function create($className, $args, $queue): Job
{
return new Some_Job_Class();
}
Expand Down
6 changes: 3 additions & 3 deletions test/Resque/Tests/JobPIDTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function testQueuedJobDoesNotReturnPID()
$this->logger->expects($this->never())
->method('log');

$token = Resque::enqueue('jobs', 'Test_Job', null, true);
$token = Resque::enqueue('jobs', 'Test_Job', [], true);
$this->assertEquals(0, PID::get($token));
}

Expand All @@ -43,14 +43,14 @@ public function testRunningJobReturnsPID()
// Cannot use InProgress_Job on non-forking OS.
if(!function_exists('pcntl_fork')) return;

$token = Resque::enqueue('jobs', 'InProgress_Job', null, true);
$token = Resque::enqueue('jobs', 'InProgress_Job', [], true);
$this->worker->work(0);
$this->assertNotEquals(0, PID::get($token));
}

public function testFinishedJobDoesNotReturnPID()
{
$token = Resque::enqueue('jobs', 'Test_Job', null, true);
$token = Resque::enqueue('jobs', 'Test_Job', [], true);
$this->worker->work(0);
$this->assertEquals(0, PID::get($token));
}
Expand Down
Loading