Skip to content

Commit 38ca53d

Browse files
committed
Add support for pushing anonymous functions onto the queue. Proceed with extreme, as in wait for me to screencast this.
1 parent bd266b0 commit 38ca53d

File tree

8 files changed

+86
-3
lines changed

8 files changed

+86
-3
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
"phpunit/phpunit": "3.7.*"
7070
},
7171
"autoload": {
72+
"classmap": [
73+
["src/Illuminate/Queue/IlluminateQueueClosure.php"]
74+
],
7275
"files": [
7376
"src/Illuminate/Support/helpers.php"
7477
],
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
class IlluminateQueueClosure {
4+
5+
/**
6+
* Fire the Closure based queue job.
7+
*
8+
* @param \Illuminate\Queue\Jobs\Job $job
9+
* @param array $data
10+
* @return void
11+
*/
12+
public function fire($job, $data)
13+
{
14+
$closure = unserialize($data['closure']);
15+
16+
$closure($job);
17+
}
18+
19+
}

src/Illuminate/Queue/Jobs/SyncJob.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php namespace Illuminate\Queue\Jobs;
22

3+
use Closure;
34
use Illuminate\Container\Container;
45

56
class SyncJob extends Job {
@@ -40,7 +41,14 @@ public function __construct(Container $container, $job, $data = '')
4041
*/
4142
public function fire()
4243
{
43-
$this->resolveAndFire(array('job' => $this->job, 'data' => $this->data));
44+
if ($this->job instanceof Closure)
45+
{
46+
call_user_func($this->job, $this, $this->data);
47+
}
48+
else
49+
{
50+
$this->resolveAndFire(array('job' => $this->job, 'data' => $this->data));
51+
}
4452
}
4553

4654
/**

src/Illuminate/Queue/Queue.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php namespace Illuminate\Queue;
22

3+
use Closure;
34
use Illuminate\Container\Container;
5+
use Illuminate\Support\SerializableClosure;
46

57
abstract class Queue {
68

@@ -30,7 +32,28 @@ public function marshal()
3032
*/
3133
protected function createPayload($job, $data = '')
3234
{
33-
return json_encode(array('job' => $job, 'data' => $data));
35+
if ($job instanceof Closure)
36+
{
37+
return json_encode($this->createClosurePayload($job, $data));
38+
}
39+
else
40+
{
41+
return json_encode(array('job' => $job, 'data' => $data));
42+
}
43+
}
44+
45+
/**
46+
* Create a payload string for the given Closure job.
47+
*
48+
* @param \Closure $job
49+
* @param mixed $data
50+
* @return string
51+
*/
52+
protected function createClosurePayload($job, $data)
53+
{
54+
$closure = serialize(new SerializableClosure($job));
55+
56+
return array('job' => 'IlluminateQueueClosure', 'data' => compact('closure'));
3457
}
3558

3659
/**

src/Illuminate/Queue/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"Illuminate\\Queue": ""
2525
},
2626
"classmap": [
27-
"Illuminate/Queue/Pheanstalk"
27+
"IlluminateQueueClosure.php"
2828
]
2929
},
3030
"target-dir": "Illuminate/Queue",

src/Illuminate/Support/SerializableClosure.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ public function unserialize($serialized)
175175
$this->reflection = new ReflectionFunction($this->closure);
176176
}
177177

178+
/**
179+
* Get the unserialized Closure instance.
180+
*
181+
* @return \Closure
182+
*/
183+
public function getClosure()
184+
{
185+
return $this->closure;
186+
}
187+
178188
/**
179189
* Invoke the contained Closure.
180190
*

tests/Queue/QueueIronQueueTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ public function testPushProperlyPushesJobOntoIron()
1818
}
1919

2020

21+
public function testPushProperlyPushesJobOntoIronWithClosures()
22+
{
23+
$queue = new Illuminate\Queue\IronQueue($iron = m::mock('IronMQ'), m::mock('Illuminate\Http\Request'), 'default');
24+
$name = 'Foo';
25+
$closure = new Illuminate\Support\SerializableClosure($innerClosure = function() use ($name) { return $name; });
26+
$iron->shouldReceive('postMessage')->once()->with('default', json_encode(array('job' => 'IlluminateQueueClosure', 'data' => array('closure' => serialize($closure)))));
27+
$queue->push($innerClosure);
28+
}
29+
30+
2131
public function testDelayedPushProperlyPushesJobOntoIron()
2232
{
2333
$queue = new Illuminate\Queue\IronQueue($iron = m::mock('IronMQ'), m::mock('Illuminate\Http\Request'), 'default');

tests/Queue/QueueSyncJobTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ public function testFireResolvesAndFiresJobClass()
2222
}
2323

2424

25+
public function testClosuresCanBeFiredBySyncJob()
26+
{
27+
unset($_SERVER['__queue.closure']);
28+
$job = new Illuminate\Queue\Jobs\SyncJob(new Illuminate\Container\Container, function() { $_SERVER['__queue.closure'] = true; }, 'data');
29+
$job->fire();
30+
31+
$this->assertTrue($_SERVER['__queue.closure']);
32+
}
33+
34+
2535
public function testFireResolvesAndFiresJobClassWithCorrectMethod()
2636
{
2737
$container = m::mock('Illuminate\Container\Container');

0 commit comments

Comments
 (0)