-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[8.x] Queued closure listeners (#33463)
Queued closure listener support.
- Loading branch information
1 parent
12ee1c4
commit 6520552
Showing
8 changed files
with
220 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace Illuminate\Events; | ||
|
||
class InvokeQueuedClosure | ||
{ | ||
/** | ||
* Handle the event. | ||
* | ||
* @param \Illuminate\Queue\SerializableClosure $closure | ||
* @param array $arguments | ||
* @return void | ||
*/ | ||
public function handle($closure, array $arguments) | ||
{ | ||
call_user_func($closure->getClosure(), ...$arguments); | ||
} | ||
|
||
/** | ||
* Handle a job failure. | ||
* | ||
* @param \Illuminate\Queue\SerializableClosure $closure | ||
* @param array $arguments | ||
* @param array $catchCallbacks | ||
* @param \Throwable $exception | ||
* @return void | ||
*/ | ||
public function failed($closure, array $arguments, array $catchCallbacks, $exception) | ||
{ | ||
$arguments[] = $exception; | ||
|
||
collect($catchCallbacks)->each->__invoke(...$arguments); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
|
||
namespace Illuminate\Events; | ||
|
||
use Closure; | ||
use Illuminate\Queue\SerializableClosure; | ||
|
||
class QueuedClosure | ||
{ | ||
/** | ||
* The underlying Closure. | ||
* | ||
* @var \Closure | ||
*/ | ||
public $closure; | ||
|
||
/** | ||
* The name of the connection the job should be sent to. | ||
* | ||
* @var string|null | ||
*/ | ||
public $connection; | ||
|
||
/** | ||
* The name of the queue the job should be sent to. | ||
* | ||
* @var string|null | ||
*/ | ||
public $queue; | ||
|
||
/** | ||
* The number of seconds before the job should be made available. | ||
* | ||
* @var \DateTimeInterface|\DateInterval|int|null | ||
*/ | ||
public $delay; | ||
|
||
/** | ||
* All of the "catch" callbacks for the queued closure. | ||
* | ||
* @var array | ||
*/ | ||
public $catchCallbacks = []; | ||
|
||
/** | ||
* Create a new queued closure event listener resolver. | ||
* | ||
* @param \Closure $closure | ||
* @return void | ||
*/ | ||
public function __construct(Closure $closure) | ||
{ | ||
$this->closure = $closure; | ||
} | ||
|
||
/** | ||
* Set the desired connection for the job. | ||
* | ||
* @param string|null $connection | ||
* @return $this | ||
*/ | ||
public function onConnection($connection) | ||
{ | ||
$this->connection = $connection; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Set the desired queue for the job. | ||
* | ||
* @param string|null $queue | ||
* @return $this | ||
*/ | ||
public function onQueue($queue) | ||
{ | ||
$this->queue = $queue; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Set the desired delay for the job. | ||
* | ||
* @param \DateTimeInterface|\DateInterval|int|null $delay | ||
* @return $this | ||
*/ | ||
public function delay($delay) | ||
{ | ||
$this->delay = $delay; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Specify a callback that should be invoked if the queued listener job fails. | ||
* | ||
* @param \Closure $closure | ||
* @return $this | ||
*/ | ||
public function catch(Closure $closure) | ||
{ | ||
$this->catchCallbacks[] = $closure; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Resolve the actual event listener callback. | ||
* | ||
* @return \Closure | ||
*/ | ||
public function resolve() | ||
{ | ||
return function (...$arguments) { | ||
dispatch(new CallQueuedListener(InvokeQueuedClosure::class, 'handle', [ | ||
'closure' => new SerializableClosure($this->closure), | ||
'arguments' => $arguments, | ||
'catch' => collect($this->catchCallbacks)->map(function ($callback) { | ||
return new SerializableClosure($callback); | ||
})->all(), | ||
]))->onConnection($this->connection)->onQueue($this->queue)->delay($this->delay); | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace Illuminate\Events; | ||
|
||
use Closure; | ||
|
||
if (! function_exists('Illuminate\Events\queueable')) { | ||
/** | ||
* Create a new queued Closure event listener. | ||
* | ||
* @param \Closure $closure | ||
* @return \Illuminate\Events\QueuedClosure | ||
*/ | ||
function queueable(Closure $closure) | ||
{ | ||
return new QueuedClosure($closure); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
namespace Illuminate\Tests\Integration\Events; | ||
|
||
use Illuminate\Events\CallQueuedListener; | ||
use Illuminate\Events\InvokeQueuedClosure; | ||
use function Illuminate\Events\queueable; | ||
use Illuminate\Support\Facades\Bus; | ||
use Illuminate\Support\Facades\Event; | ||
use Orchestra\Testbench\TestCase; | ||
|
||
class QueuedClosureListenerTest extends TestCase | ||
{ | ||
public function testAnonymousQueuedListenerIsQueued() | ||
{ | ||
Bus::fake(); | ||
|
||
Event::listen(queueable(function (TestEvent $event) { | ||
// | ||
})->catch(function (TestEvent $event) { | ||
// | ||
})->onConnection(null)->onQueue(null)); | ||
|
||
Event::dispatch(new TestEvent); | ||
|
||
Bus::assertDispatched(CallQueuedListener::class, function ($job) { | ||
return $job->class == InvokeQueuedClosure::class; | ||
}); | ||
} | ||
} | ||
|
||
class TestEvent | ||
{ | ||
// | ||
} |