Skip to content

Commit a95c24b

Browse files
committed
add beforeEnqueue hook that allows the enqueue to be cancelled
1 parent c335bc3 commit a95c24b

File tree

5 files changed

+106
-29
lines changed

5 files changed

+106
-29
lines changed

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,18 @@ Called whenever a job fails. Arguments passed (in this order) include:
413413
* Exception - The exception that was thrown when the job failed
414414
* Resque_Job - The job that failed
415415

416+
#### beforeEnqueue ####
417+
418+
Called immediately before a job is enqueued using the `Resque::enqueue` method.
419+
Arguments passed (in this order) include:
420+
421+
* Class - string containing the name of the job to be enqueued
422+
* Arguments - array of arguments for the job
423+
* Queue - string containing the name of the queue the job is to be enqueued in
424+
* ID - string containing the token of the job to be enqueued
425+
426+
You can prevent enqueing of the job by throwing an exception of `Resque_Job_DontCreate`.
427+
416428
#### afterEnqueue ####
417429

418430
Called after a job has been queued using the `Resque::enqueue` method. Arguments passed

lib/Resque.php

+26-9
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,24 @@ public static function size($queue)
201201
*/
202202
public static function enqueue($queue, $class, $args = null, $trackStatus = false)
203203
{
204-
$result = Resque_Job::create($queue, $class, $args, $trackStatus);
205-
if ($result) {
206-
Resque_Event::trigger('afterEnqueue', array(
207-
'class' => $class,
208-
'args' => $args,
209-
'queue' => $queue,
210-
'id' => $result,
211-
));
204+
$id = Resque::generateJobId();
205+
$hookParams = array(
206+
'class' => $class,
207+
'args' => $args,
208+
'queue' => $queue,
209+
'id' => $id,
210+
);
211+
try {
212+
Resque_Event::trigger('beforeEnqueue', $hookParams);
212213
}
214+
catch(Resque_Job_DontCreate $e) {
215+
return $id;
216+
}
217+
218+
Resque_Job::create($queue, $class, $args, $trackStatus, $id);
219+
Resque_Event::trigger('afterEnqueue', $hookParams);
213220

214-
return $result;
221+
return $id;
215222
}
216223

217224
/**
@@ -341,5 +348,15 @@ private static function removeList($queue)
341348
$result = self::redis()->del('queue:' . $queue);
342349
return ($result == 1) ? $counter : 0;
343350
}
351+
352+
/*
353+
* Generate an identifier to attach to a job for status tracking.
354+
*
355+
* @return string
356+
*/
357+
public static function generateJobId()
358+
{
359+
return md5(uniqid('', true));
360+
}
344361
}
345362

lib/Resque/Job.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,17 @@ public function __construct($queue, $payload)
5050
*
5151
* @return string
5252
*/
53-
public static function create($queue, $class, $args = null, $monitor = false)
53+
public static function create($queue, $class, $args = null, $monitor = false, $id = null)
5454
{
55+
if (is_null($id)) {
56+
$id = Resque::generateJobId();
57+
}
58+
5559
if($args !== null && !is_array($args)) {
5660
throw new InvalidArgumentException(
5761
'Supplied $args must be an array.'
5862
);
5963
}
60-
$id = md5(uniqid('', true));
6164
Resque::push($queue, array(
6265
'class' => $class,
6366
'args' => array($args),

lib/Resque/Job/DontCreate.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
/**
3+
* Exception to be thrown if while enqueuing a job it should not be created.
4+
*
5+
* @package Resque/Job
6+
* @author Chris Boulton <[email protected]>
7+
* @license http://www.opensource.org/licenses/mit-license.php
8+
*/
9+
class Resque_Job_DontCreate extends Exception
10+
{
11+
12+
}

test/Resque/Tests/EventTest.php

+51-18
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
class Resque_Tests_EventTest extends Resque_Tests_TestCase
1010
{
1111
private $callbacksHit = array();
12-
12+
1313
public function setUp()
1414
{
1515
Test_Job::$called = false;
16-
16+
1717
// Register a worker to test with
1818
$this->worker = new Resque_Worker('jobs');
1919
$this->worker->setLogger(new Resque_Log());
@@ -38,7 +38,7 @@ public function getEventTestJob()
3838
$job->worker = $this->worker;
3939
return $job;
4040
}
41-
41+
4242
public function eventCallbackProvider()
4343
{
4444
return array(
@@ -47,7 +47,7 @@ public function eventCallbackProvider()
4747
array('afterFork', 'afterForkEventCallback'),
4848
);
4949
}
50-
50+
5151
/**
5252
* @dataProvider eventCallbackProvider
5353
*/
@@ -58,10 +58,10 @@ public function testEventCallbacksFire($event, $callback)
5858
$job = $this->getEventTestJob();
5959
$this->worker->perform($job);
6060
$this->worker->work(0);
61-
61+
6262
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called');
6363
}
64-
64+
6565
public function testBeforeForkEventCallbackFires()
6666
{
6767
$event = 'beforeFork';
@@ -76,6 +76,18 @@ public function testBeforeForkEventCallbackFires()
7676
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called');
7777
}
7878

79+
public function testBeforeEnqueueEventCallbackFires()
80+
{
81+
$event = 'beforeEnqueue';
82+
$callback = 'beforeEnqueueEventCallback';
83+
84+
Resque_Event::listen($event, array($this, $callback));
85+
Resque::enqueue('jobs', 'Test_Job', array(
86+
'somevar'
87+
));
88+
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called');
89+
}
90+
7991
public function testBeforePerformEventCanStopWork()
8092
{
8193
$callback = 'beforePerformEventDontPerformCallback';
@@ -87,23 +99,34 @@ public function testBeforePerformEventCanStopWork()
8799
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
88100
$this->assertFalse(Test_Job::$called, 'Job was still performed though Resque_Job_DontPerform was thrown');
89101
}
90-
102+
103+
public function testBeforeEnqueueEventStopsJobCreation()
104+
{
105+
$callback = 'beforeEnqueueEventDontCreateCallback';
106+
Resque_Event::listen('beforeEnqueue', array($this, $callback));
107+
Resque_Event::listen('afterEnqueue', array($this, 'afterEnqueueEventCallback'));
108+
109+
Resque::enqueue('test_job', 'TestClass');
110+
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
111+
$this->assertNotContains('afterEnqueueEventCallback', $this->callbacksHit, 'afterEnqueue was still called, even though it should not have been');
112+
}
113+
91114
public function testAfterEnqueueEventCallbackFires()
92115
{
93116
$callback = 'afterEnqueueEventCallback';
94-
$event = 'afterEnqueue';
95-
117+
$event = 'afterEnqueue';
118+
96119
Resque_Event::listen($event, array($this, $callback));
97120
Resque::enqueue('jobs', 'Test_Job', array(
98121
'somevar'
99-
));
122+
));
100123
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called');
101124
}
102125

103126
public function testStopListeningRemovesListener()
104127
{
105128
$callback = 'beforePerformEventCallback';
106-
$event = 'beforePerform';
129+
$event = 'beforePerform';
107130

108131
Resque_Event::listen($event, array($this, $callback));
109132
Resque_Event::stopListening($event, array($this, $callback));
@@ -112,18 +135,23 @@ public function testStopListeningRemovesListener()
112135
$this->worker->perform($job);
113136
$this->worker->work(0);
114137

115-
$this->assertNotContains($callback, $this->callbacksHit,
138+
$this->assertNotContains($callback, $this->callbacksHit,
116139
$event . ' callback (' . $callback .') was called though Resque_Event::stopListening was called'
117140
);
118141
}
119142

120-
121143
public function beforePerformEventDontPerformCallback($instance)
122144
{
123145
$this->callbacksHit[] = __FUNCTION__;
124146
throw new Resque_Job_DontPerform;
125147
}
126-
148+
149+
public function beforeEnqueueEventDontCreateCallback($queue, $class, $args, $track = false)
150+
{
151+
$this->callbacksHit[] = __FUNCTION__;
152+
throw new Resque_Job_DontCreate;
153+
}
154+
127155
public function assertValidEventCallback($function, $job)
128156
{
129157
$this->callbacksHit[] = $function;
@@ -133,7 +161,7 @@ public function assertValidEventCallback($function, $job)
133161
$args = $job->getArguments();
134162
$this->assertEquals($args[0], 'somevar');
135163
}
136-
164+
137165
public function afterEnqueueEventCallback($class, $args)
138166
{
139167
$this->callbacksHit[] = __FUNCTION__;
@@ -142,12 +170,17 @@ public function afterEnqueueEventCallback($class, $args)
142170
'somevar',
143171
), $args);
144172
}
145-
173+
174+
public function beforeEnqueueEventCallback($job)
175+
{
176+
$this->callbacksHit[] = __FUNCTION__;
177+
}
178+
146179
public function beforePerformEventCallback($job)
147180
{
148181
$this->assertValidEventCallback(__FUNCTION__, $job);
149182
}
150-
183+
151184
public function afterPerformEventCallback($job)
152185
{
153186
$this->assertValidEventCallback(__FUNCTION__, $job);
@@ -157,7 +190,7 @@ public function beforeForkEventCallback($job)
157190
{
158191
$this->assertValidEventCallback(__FUNCTION__, $job);
159192
}
160-
193+
161194
public function afterForkEventCallback($job)
162195
{
163196
$this->assertValidEventCallback(__FUNCTION__, $job);

0 commit comments

Comments
 (0)