mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 13:54:03 +00:00
Extract JobPipelines to a separate package
This commit is contained in:
parent
1008db2d43
commit
1833622170
12 changed files with 11 additions and 285 deletions
|
|
@ -5,7 +5,7 @@ namespace App\Providers;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Events\DatabaseCreated;
|
use Stancl\Tenancy\Events\DatabaseCreated;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"illuminate/support": "^6.0|^7.0",
|
"illuminate/support": "^6.0|^7.0",
|
||||||
"facade/ignition-contracts": "^1.0",
|
"facade/ignition-contracts": "^1.0",
|
||||||
"ramsey/uuid": "^3.7|^4.0"
|
"ramsey/uuid": "^3.7|^4.0",
|
||||||
|
"stancl/jobpipeline": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"vlucas/phpdotenv": "^3.3|^4.0",
|
"vlucas/phpdotenv": "^3.3|^4.0",
|
||||||
|
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Listeners;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
|
|
||||||
class JobPipeline implements ShouldQueue
|
|
||||||
{
|
|
||||||
/** @var bool */
|
|
||||||
public static $shouldBeQueuedByDefault = false;
|
|
||||||
|
|
||||||
/** @var callable[]|string[] */
|
|
||||||
public $jobs;
|
|
||||||
|
|
||||||
/** @var callable|null */
|
|
||||||
public $send;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A value passed to the jobs. This is the return value of $send.
|
|
||||||
*/
|
|
||||||
public $passable;
|
|
||||||
|
|
||||||
/** @var bool */
|
|
||||||
public $shouldBeQueued;
|
|
||||||
|
|
||||||
public function __construct($jobs, callable $send = null, bool $shouldBeQueued = null)
|
|
||||||
{
|
|
||||||
$this->jobs = $jobs;
|
|
||||||
$this->send = $send ?? function ($event) {
|
|
||||||
// If no $send callback is set, we'll just pass the event through the jobs.
|
|
||||||
return $event;
|
|
||||||
};
|
|
||||||
$this->shouldBeQueued = $shouldBeQueued ?? static::$shouldBeQueuedByDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param callable[]|string[] $jobs */
|
|
||||||
public static function make(array $jobs): self
|
|
||||||
{
|
|
||||||
return new static($jobs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function send(callable $send): self
|
|
||||||
{
|
|
||||||
$this->send = $send;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function shouldBeQueued(bool $shouldBeQueued)
|
|
||||||
{
|
|
||||||
$this->shouldBeQueued = $shouldBeQueued;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle(): void
|
|
||||||
{
|
|
||||||
foreach ($this->jobs as $job) {
|
|
||||||
app()->call([new $job(...$this->passable), 'handle']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a closure that can be used as a listener.
|
|
||||||
*/
|
|
||||||
public function toListener(): Closure
|
|
||||||
{
|
|
||||||
return function (...$args) {
|
|
||||||
$executable = $this->executable($args);
|
|
||||||
|
|
||||||
if ($this->shouldBeQueued) {
|
|
||||||
dispatch($executable);
|
|
||||||
} else {
|
|
||||||
dispatch_now($executable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a serializable version of the current object.
|
|
||||||
*/
|
|
||||||
public function executable($listenerArgs): self
|
|
||||||
{
|
|
||||||
$clone = clone $this;
|
|
||||||
|
|
||||||
$passable = ($clone->send)(...$listenerArgs);
|
|
||||||
$passable = is_array($passable) ? $passable : [$passable];
|
|
||||||
|
|
||||||
$clone->passable = $passable;
|
|
||||||
unset($clone->send);
|
|
||||||
|
|
||||||
return $clone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Redis;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use Illuminate\Support\Facades\Schema;
|
||||||
use Stancl\Tenancy\Tests\Etc\ExampleSeeder;
|
use Stancl\Tenancy\Tests\Etc\ExampleSeeder;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
|
|
|
||||||
|
|
@ -1,180 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Tests;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
|
||||||
use Illuminate\Support\Facades\Queue;
|
|
||||||
use Spatie\Valuestore\Valuestore;
|
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
|
||||||
|
|
||||||
class JobPipelineTest extends TestCase
|
|
||||||
{
|
|
||||||
public $mockConsoleOutput = false;
|
|
||||||
|
|
||||||
/** @var Valuestore */
|
|
||||||
protected $valuestore;
|
|
||||||
|
|
||||||
public function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
config(['queue.default' => 'redis']);
|
|
||||||
|
|
||||||
$this->valuestore = Valuestore::make(__DIR__ . '/Etc/tmp/jobpipelinetest.json')->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function job_pipeline_can_listen_to_any_event()
|
|
||||||
{
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([
|
|
||||||
FooJob::class,
|
|
||||||
])->send(function () {
|
|
||||||
return $this->valuestore;
|
|
||||||
})->toListener());
|
|
||||||
|
|
||||||
$this->assertFalse($this->valuestore->has('foo'));
|
|
||||||
|
|
||||||
Tenant::create();
|
|
||||||
|
|
||||||
$this->assertSame('bar', $this->valuestore->get('foo'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function job_pipeline_can_be_queued()
|
|
||||||
{
|
|
||||||
Queue::fake();
|
|
||||||
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([
|
|
||||||
FooJob::class,
|
|
||||||
])->send(function () {
|
|
||||||
return $this->valuestore;
|
|
||||||
})->shouldBeQueued(true)->toListener());
|
|
||||||
|
|
||||||
Queue::assertNothingPushed();
|
|
||||||
|
|
||||||
Tenant::create();
|
|
||||||
$this->assertFalse($this->valuestore->has('foo'));
|
|
||||||
|
|
||||||
Queue::pushed(JobPipeline::class, function (JobPipeline $pipeline) {
|
|
||||||
$this->assertSame([FooJob::class], $pipeline->jobs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function job_pipelines_run_when_queued()
|
|
||||||
{
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([
|
|
||||||
FooJob::class,
|
|
||||||
])->send(function () {
|
|
||||||
return $this->valuestore;
|
|
||||||
})->shouldBeQueued(true)->toListener());
|
|
||||||
|
|
||||||
$this->assertFalse($this->valuestore->has('foo'));
|
|
||||||
Tenant::create();
|
|
||||||
$this->artisan('queue:work --once');
|
|
||||||
|
|
||||||
$this->assertSame('bar', $this->valuestore->get('foo'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function job_pipeline_executes_jobs_and_passes_the_object_sequentially()
|
|
||||||
{
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([
|
|
||||||
FirstJob::class,
|
|
||||||
SecondJob::class,
|
|
||||||
])->send(function (TenantCreated $event) {
|
|
||||||
return [$event->tenant, $this->valuestore];
|
|
||||||
})->toListener());
|
|
||||||
|
|
||||||
$this->assertFalse($this->valuestore->has('foo'));
|
|
||||||
|
|
||||||
Tenant::create();
|
|
||||||
|
|
||||||
$this->assertSame('first job changed property', $this->valuestore->get('foo'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function send_can_return_multiple_arguments()
|
|
||||||
{
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([
|
|
||||||
JobWithMultipleArguments::class
|
|
||||||
])->send(function () {
|
|
||||||
return ['a', 'b'];
|
|
||||||
})->toListener());
|
|
||||||
|
|
||||||
$this->assertFalse(app()->bound('test_args'));
|
|
||||||
|
|
||||||
Tenant::create();
|
|
||||||
|
|
||||||
$this->assertSame(['a', 'b'], app('test_args'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FooJob
|
|
||||||
{
|
|
||||||
protected $valuestore;
|
|
||||||
|
|
||||||
public function __construct(Valuestore $valuestore)
|
|
||||||
{
|
|
||||||
$this->valuestore = $valuestore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$this->valuestore->put('foo', 'bar');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class FirstJob
|
|
||||||
{
|
|
||||||
public $tenant;
|
|
||||||
|
|
||||||
public function __construct(Tenant $tenant)
|
|
||||||
{
|
|
||||||
$this->tenant = $tenant;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$this->tenant->foo = 'first job changed property';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SecondJob
|
|
||||||
{
|
|
||||||
public $tenant;
|
|
||||||
|
|
||||||
protected $valuestore;
|
|
||||||
|
|
||||||
public function __construct(Tenant $tenant, Valuestore $valuestore)
|
|
||||||
{
|
|
||||||
$this->tenant = $tenant;
|
|
||||||
$this->valuestore = $valuestore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$this->valuestore->put('foo', $this->tenant->foo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JobWithMultipleArguments
|
|
||||||
{
|
|
||||||
protected $first;
|
|
||||||
protected $second;
|
|
||||||
|
|
||||||
public function __construct($first, $second)
|
|
||||||
{
|
|
||||||
$this->first = $first;
|
|
||||||
$this->second = $second;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
// we dont queue this job so no need to use valuestore here
|
|
||||||
app()->instance('test_args', [$this->first, $this->second]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,7 @@ use Stancl\Tenancy\Database\Concerns\ResourceSyncing;
|
||||||
use Stancl\Tenancy\Database\Models\TenantPivot;
|
use Stancl\Tenancy\Database\Models\TenantPivot;
|
||||||
use Stancl\Tenancy\DatabaseConfig;
|
use Stancl\Tenancy\DatabaseConfig;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Listeners\UpdateSyncedResource;
|
use Stancl\Tenancy\Listeners\UpdateSyncedResource;
|
||||||
use Stancl\Tenancy\Events\SyncedResourceChangedInForeignDatabase;
|
use Stancl\Tenancy\Events\SyncedResourceChangedInForeignDatabase;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\DatabaseManager;
|
use Stancl\Tenancy\DatabaseManager;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
|
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Stancl\Tenancy\Database\TenantCollection;
|
use Stancl\Tenancy\Database\TenantCollection;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue