1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 16:24:04 +00:00

JobPipeline now works fully

This commit is contained in:
Samuel Štancl 2020-05-08 16:57:14 +02:00
parent 7a2e6bb13e
commit 08ed5084d5
3 changed files with 37 additions and 39 deletions

View file

@ -63,7 +63,7 @@ class TenancyServiceProvider extends ServiceProvider
foreach ($this->events() as $event => $listeners) { foreach ($this->events() as $event => $listeners) {
foreach (array_unique($listeners) as $listener) { foreach (array_unique($listeners) as $listener) {
if ($listener instanceof JobPipeline) { if ($listener instanceof JobPipeline) {
$listener = $listener->toClosure(); $listener = $listener->toListener();
} }
Event::listen($event, $listener); Event::listen($event, $listener);

View file

@ -4,7 +4,6 @@ namespace Stancl\Tenancy\Events\Listeners;
use Closure; use Closure;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Pipeline\Pipeline;
class JobPipeline implements ShouldQueue class JobPipeline implements ShouldQueue
{ {
@ -12,13 +11,18 @@ class JobPipeline implements ShouldQueue
public static $shouldQueueByDefault = true; public static $shouldQueueByDefault = true;
/** @var callable[]|string[] */ /** @var callable[]|string[] */
public $jobs = []; public $jobs;
/** @var callable */ /** @var callable|null */
public $send; public $send;
/**
* A value passed to the jobs. This is the return value of $send.
*/
public $passable;
/** @var bool */ /** @var bool */
public $shouldQueue = true; public $shouldQueue;
public function __construct($jobs, callable $send = null, bool $shouldQueue = null) public function __construct($jobs, callable $send = null, bool $shouldQueue = null)
{ {
@ -36,13 +40,6 @@ class JobPipeline implements ShouldQueue
return new static($jobs); return new static($jobs);
} }
public function queue(bool $shouldQueue): self
{
$this->shouldQueue = $shouldQueue;
return $this;
}
public function send(callable $send): self public function send(callable $send): self
{ {
$this->send = $send; $this->send = $send;
@ -50,7 +47,6 @@ class JobPipeline implements ShouldQueue
return $this; return $this;
} }
/** @return bool|$this */
public function shouldQueue(bool $shouldQueue = null) public function shouldQueue(bool $shouldQueue = null)
{ {
if ($shouldQueue !== null) { if ($shouldQueue !== null) {
@ -62,30 +58,33 @@ class JobPipeline implements ShouldQueue
return $this->shouldQueue; return $this->shouldQueue;
} }
public function handle($event): void public function handle(): void
{ {
/** @var Pipeline $pipeline */ foreach ($this->jobs as $job) {
$pipeline = app(Pipeline::class); app($job)->handle($this->passable);
}
$pipeline
->send(($this->send)($event))
->through($this->jobs)
->thenReturn();
} }
/** /**
* Generate a closure that runs this listener. * Generate a closure that can be used as a listener.
*
* Technically, the string|Closure typehint is not enforced by
* Laravel, but for correct typing we wrap this callable in
* simple Closures, to match Laravel's docblock typehint.
*
* @return Closure
*/ */
public function toClosure(): Closure public function toListener(): Closure
{ {
return function (...$args) { return function (...$args) {
$this->handle(...$args); dispatch($this->queueFriendly($args));
}; };
} }
/**
* Return a serializable version of the current object.
*/
public function queueFriendly($listenerArgs): self
{
$clone = clone $this;
$clone->passable = ($clone->send)(...$listenerArgs);
unset($clone->send);
return $clone;
}
} }

View file

@ -16,7 +16,7 @@ class JobPipelineTest extends TestCase
{ {
Event::listen(TenantCreated::class, JobPipeline::make([ Event::listen(TenantCreated::class, JobPipeline::make([
FooJob::class, FooJob::class,
])->toClosure()); ])->toListener());
$this->assertFalse(app()->bound('foo')); $this->assertFalse(app()->bound('foo'));
@ -28,20 +28,20 @@ class JobPipelineTest extends TestCase
/** @test */ /** @test */
public function job_pipeline_can_be_queued() public function job_pipeline_can_be_queued()
{ {
// todo: This does not work because of toClosure
Queue::fake(); Queue::fake();
Event::listen(TenantCreated::class, JobPipeline::make([ Event::listen(TenantCreated::class, JobPipeline::make([
FooJob::class, FooJob::class,
])->queue(true)->toClosure()); ])->shouldQueue(true)->toListener());
Queue::assertNothingPushed(); Queue::assertNothingPushed();
Tenant::create(); Tenant::create();
$this->assertFalse(app()->bound('foo')); $this->assertFalse(app()->bound('foo'));
Queue::assertPushed(JobPipeline::class); Queue::pushed(JobPipeline::class, function (JobPipeline $pipeline) {
$this->assertSame([FooJob::class], $pipeline->jobs);
});
} }
/** @test */ /** @test */
@ -52,11 +52,10 @@ class JobPipelineTest extends TestCase
SecondJob::class, SecondJob::class,
])->send(function (TenantCreated $event) { ])->send(function (TenantCreated $event) {
return $event->tenant; return $event->tenant;
})->toClosure()); })->toListener());
$this->assertFalse(app()->bound('foo')); $this->assertFalse(app()->bound('foo'));
// todo: for some reason, SecondJob is not reached in the pipeline
Tenant::create(); Tenant::create();
$this->assertSame('first job changed property', app('foo')); $this->assertSame('first job changed property', app('foo'));