Skip to content

Commit ee9f133

Browse files
authored
Merge pull request #303 from serroba/BIG-28720
Allowing to use a factory instead of manually instantiate the Jobs
2 parents e9a202c + be19e12 commit ee9f133

File tree

7 files changed

+198
-62
lines changed

7 files changed

+198
-62
lines changed

lib/Resque/Job.php

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ class Resque_Job
2424
public $payload;
2525

2626
/**
27-
* @var object Instance of the class performing work for this job.
27+
* @var object|Resque_JobInterface Instance of the class performing work for this job.
2828
*/
2929
private $instance;
3030

31+
/**
32+
* @var Resque_Job_FactoryInterface
33+
*/
34+
private $jobFactory;
35+
3136
/**
3237
* Instantiate a new instance of a job.
3338
*
@@ -50,6 +55,7 @@ public function __construct($queue, $payload)
5055
* @param string $id Unique identifier for tracking the job. Generated if not supplied.
5156
*
5257
* @return string
58+
* @throws \InvalidArgumentException
5359
*/
5460
public static function create($queue, $class, $args = null, $monitor = false, $id = null)
5561
{
@@ -76,41 +82,41 @@ public static function create($queue, $class, $args = null, $monitor = false, $i
7682
return $id;
7783
}
7884

79-
/**
80-
* Find the next available job from the specified queue and return an
81-
* instance of Resque_Job for it.
82-
*
83-
* @param string $queue The name of the queue to check for a job in.
84-
* @return null|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
85-
*/
86-
public static function reserve($queue)
87-
{
88-
$payload = Resque::pop($queue);
89-
if(!is_array($payload)) {
90-
return false;
91-
}
85+
/**
86+
* Find the next available job from the specified queue and return an
87+
* instance of Resque_Job for it.
88+
*
89+
* @param string $queue The name of the queue to check for a job in.
90+
* @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
91+
*/
92+
public static function reserve($queue)
93+
{
94+
$payload = Resque::pop($queue);
95+
if(!is_array($payload)) {
96+
return false;
97+
}
9298

93-
return new Resque_Job($queue, $payload);
94-
}
99+
return new Resque_Job($queue, $payload);
100+
}
95101

96-
/**
97-
* Find the next available job from the specified queues using blocking list pop
98-
* and return an instance of Resque_Job for it.
99-
*
100-
* @param array $queues
101-
* @param int $timeout
102-
* @return null|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
103-
*/
104-
public static function reserveBlocking(array $queues, $timeout = null)
105-
{
106-
$item = Resque::blpop($queues, $timeout);
102+
/**
103+
* Find the next available job from the specified queues using blocking list pop
104+
* and return an instance of Resque_Job for it.
105+
*
106+
* @param array $queues
107+
* @param int $timeout
108+
* @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
109+
*/
110+
public static function reserveBlocking(array $queues, $timeout = null)
111+
{
112+
$item = Resque::blpop($queues, $timeout);
107113

108-
if(!is_array($item)) {
109-
return false;
110-
}
114+
if(!is_array($item)) {
115+
return false;
116+
}
111117

112-
return new Resque_Job($item['queue'], $item['payload']);
113-
}
118+
return new Resque_Job($item['queue'], $item['payload']);
119+
}
114120

115121
/**
116122
* Update the status of the current job.
@@ -154,32 +160,18 @@ public function getArguments()
154160

155161
/**
156162
* Get the instantiated object for this job that will be performing work.
157-
*
158-
* @return object Instance of the object that this job belongs to.
163+
* @return Resque_JobInterface Instance of the object that this job belongs to.
164+
* @throws Resque_Exception
159165
*/
160166
public function getInstance()
161167
{
162168
if (!is_null($this->instance)) {
163169
return $this->instance;
164170
}
165171

166-
if(!class_exists($this->payload['class'])) {
167-
throw new Resque_Exception(
168-
'Could not find job class ' . $this->payload['class'] . '.'
169-
);
170-
}
171-
172-
if(!method_exists($this->payload['class'], 'perform')) {
173-
throw new Resque_Exception(
174-
'Job class ' . $this->payload['class'] . ' does not contain a perform method.'
175-
);
176-
}
177-
178-
$this->instance = new $this->payload['class'];
179-
$this->instance->job = $this;
180-
$this->instance->args = $this->getArguments();
181-
$this->instance->queue = $this->queue;
182-
return $this->instance;
172+
$this->instance = $this->getJobFactory()->create($this->payload['class'], $this->getArguments(), $this->queue);
173+
$this->instance->job = $this;
174+
return $this->instance;
183175
}
184176

185177
/**
@@ -272,4 +264,26 @@ public function __toString()
272264
}
273265
return '(' . implode(' | ', $name) . ')';
274266
}
267+
268+
/**
269+
* @param Resque_Job_FactoryInterface $jobFactory
270+
* @return Resque_Job
271+
*/
272+
public function setJobFactory(Resque_Job_FactoryInterface $jobFactory)
273+
{
274+
$this->jobFactory = $jobFactory;
275+
276+
return $this;
277+
}
278+
279+
/**
280+
* @return Resque_Job_FactoryInterface
281+
*/
282+
public function getJobFactory()
283+
{
284+
if ($this->jobFactory === null) {
285+
$this->jobFactory = new Resque_Job_Factory();
286+
}
287+
return $this->jobFactory;
288+
}
275289
}

lib/Resque/Job/Factory.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
class Resque_Job_Factory implements Resque_Job_FactoryInterface
4+
{
5+
6+
/**
7+
* @param $className
8+
* @param array $args
9+
* @param $queue
10+
* @return Resque_JobInterface
11+
* @throws \Resque_Exception
12+
*/
13+
public function create($className, $args, $queue)
14+
{
15+
if (!class_exists($className)) {
16+
throw new Resque_Exception(
17+
'Could not find job class ' . $className . '.'
18+
);
19+
}
20+
21+
if (!method_exists($className, 'perform')) {
22+
throw new Resque_Exception(
23+
'Job class ' . $className . ' does not contain a perform method.'
24+
);
25+
}
26+
27+
$instance = new $className;
28+
$instance->args = $args;
29+
$instance->queue = $queue;
30+
return $instance;
31+
}
32+
}

lib/Resque/Job/FactoryInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
interface Resque_Job_FactoryInterface
4+
{
5+
/**
6+
* @param $className
7+
* @param array $args
8+
* @param $queue
9+
* @return Resque_JobInterface
10+
*/
11+
public function create($className, $args, $queue);
12+
}

lib/Resque/JobInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
interface Resque_JobInterface
4+
{
5+
/**
6+
* @return bool
7+
*/
8+
public function perform();
9+
}

test/Resque/Tests/EventTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function getEventTestJob()
3131
$payload = array(
3232
'class' => 'Test_Job',
3333
'args' => array(
34-
'somevar',
34+
array('somevar'),
3535
),
3636
);
3737
$job = new Resque_Job('jobs', $payload);

test/Resque/Tests/JobTest.php

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,16 @@ public function testNamespaceNaming() {
183183

184184
public function testJobWithNamespace()
185185
{
186-
Resque_Redis::prefix('php');
187-
$queue = 'jobs';
188-
$payload = array('another_value');
189-
Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload);
190-
191-
$this->assertEquals(Resque::queues(), array('jobs'));
192-
$this->assertEquals(Resque::size($queue), 1);
186+
Resque_Redis::prefix('php');
187+
$queue = 'jobs';
188+
$payload = array('another_value');
189+
Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload);
190+
191+
$this->assertEquals(Resque::queues(), array('jobs'));
192+
$this->assertEquals(Resque::size($queue), 1);
193193

194-
Resque_Redis::prefix('resque');
195-
$this->assertEquals(Resque::size($queue), 0);
194+
Resque_Redis::prefix('resque');
195+
$this->assertEquals(Resque::size($queue), 0);
196196
}
197197

198198
public function testDequeueAll()
@@ -362,4 +362,68 @@ public function testDequeueItemWithiWrongArg()
362362
$this->assertEquals(Resque::size($queue), 2);
363363
}
364364

365+
public function testUseDefaultFactoryToGetJobInstance()
366+
{
367+
$payload = array(
368+
'class' => 'Some_Job_Class',
369+
'args' => null
370+
);
371+
$job = new Resque_Job('jobs', $payload);
372+
$instance = $job->getInstance();
373+
$this->assertInstanceOf('Some_Job_Class', $instance);
374+
}
375+
376+
public function testUseFactoryToGetJobInstance()
377+
{
378+
$payload = array(
379+
'class' => 'Some_Job_Class',
380+
'args' => array(array())
381+
);
382+
$job = new Resque_Job('jobs', $payload);
383+
$factory = new Some_Stub_Factory();
384+
$job->setJobFactory($factory);
385+
$instance = $job->getInstance();
386+
$this->assertInstanceOf('Resque_JobInterface', $instance);
387+
}
388+
389+
public function testDoNotUseFactoryToGetInstance()
390+
{
391+
$payload = array(
392+
'class' => 'Some_Job_Class',
393+
'args' => array(array())
394+
);
395+
$job = new Resque_Job('jobs', $payload);
396+
$factory = $this->getMock('Resque_Job_FactoryInterface');
397+
$testJob = $this->getMock('Resque_JobInterface');
398+
$factory->expects(self::never())->method('create')->will(self::returnValue($testJob));
399+
$instance = $job->getInstance();
400+
$this->assertInstanceOf('Resque_JobInterface', $instance);
401+
}
402+
}
403+
404+
class Some_Job_Class implements Resque_JobInterface
405+
{
406+
407+
/**
408+
* @return bool
409+
*/
410+
public function perform()
411+
{
412+
return true;
413+
}
414+
}
415+
416+
class Some_Stub_Factory implements Resque_Job_FactoryInterface
417+
{
418+
419+
/**
420+
* @param $className
421+
* @param array $args
422+
* @param $queue
423+
* @return Resque_JobInterface
424+
*/
425+
public function create($className, $args, $queue)
426+
{
427+
return new Some_Job_Class();
428+
}
365429
}

test/Resque/Tests/TestCase.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ class Resque_Tests_TestCase extends PHPUnit_Framework_TestCase
1111
protected $resque;
1212
protected $redis;
1313

14+
public static function setUpBeforeClass()
15+
{
16+
date_default_timezone_set('UTC');
17+
}
18+
1419
public function setUp()
1520
{
1621
$config = file_get_contents(REDIS_CONF);
@@ -20,4 +25,4 @@ public function setUp()
2025
// Flush redis
2126
$this->redis->flushAll();
2227
}
23-
}
28+
}

0 commit comments

Comments
 (0)