diff --git a/src/Search/Commands/Update.php b/src/Search/Commands/Update.php index 349d0066040..ca398006f0b 100644 --- a/src/Search/Commands/Update.php +++ b/src/Search/Commands/Update.php @@ -15,7 +15,9 @@ class Update extends Command protected $signature = 'statamic:search:update { index? : The handle of the index to update. } - { --all : Update all indexes. }'; + { --all : Update all indexes. } + { --connection= : The queue connection used for indexing jobs. } + { --queue= : The queue name used for indexing jobs. }'; protected $description = 'Update a search index'; @@ -24,6 +26,14 @@ class Update extends Command public function handle() { foreach ($this->getIndexes() as $index) { + if ($connection = $this->option('connection')) { + $index->onConnection($connection); + } + + if ($queue = $this->option('queue')) { + $index->onQueue($queue); + } + $index->update(); SearchIndexUpdated::dispatch($index); diff --git a/src/Search/Index.php b/src/Search/Index.php index c4422dbb7f5..84c93d4750d 100644 --- a/src/Search/Index.php +++ b/src/Search/Index.php @@ -12,6 +12,8 @@ abstract class Index protected $handle; protected $locale; protected $config; + protected ?string $queue = null; + protected ?string $queueConnection = null; protected static ?Closure $nameCallback = null; abstract public function search($query); @@ -98,11 +100,37 @@ public function insertMultiple($documents) { $documents ->chunk(config('statamic.search.chunk_size')) - ->each(fn ($documents) => InsertMultipleJob::dispatch( - name: $this->handle, - locale: $this->locale, - documents: $documents - )); + ->each(function ($documents) { + $job = new InsertMultipleJob( + name: $this->handle, + locale: $this->locale, + documents: $documents + ); + + if ($this->queueConnection) { + $job->onConnection($this->queueConnection); + } + + if ($this->queue) { + $job->onQueue($this->queue); + } + + dispatch($job); + }); + + return $this; + } + + public function onConnection(string $connection) + { + $this->queueConnection = $connection; + + return $this; + } + + public function onQueue(string $queue) + { + $this->queue = $queue; return $this; } diff --git a/tests/Search/Commands/UpdateTest.php b/tests/Search/Commands/UpdateTest.php index b165ae00651..3eb378094c0 100644 --- a/tests/Search/Commands/UpdateTest.php +++ b/tests/Search/Commands/UpdateTest.php @@ -2,7 +2,9 @@ namespace Tests\Search\Commands; +use Mockery; use PHPUnit\Framework\Attributes\Test; +use Statamic\Facades\Search; use Statamic\Search\Commands\Update; use Statamic\Search\Index; use Tests\TestCase; @@ -17,6 +19,17 @@ public function tearDown(): void parent::tearDown(); } + private function fakeIndex() + { + $index = Mockery::mock(Index::class); + $index->shouldReceive('name')->andReturn('test'); + $index->shouldReceive('update')->once(); + + Search::shouldReceive('indexes')->andReturn(collect(['test' => $index])); + + return $index; + } + private function setUpIndexes() { $this->setSites([ @@ -60,6 +73,44 @@ public function it_updates_the_localized_indexes_when_the_names_have_been_custom ->assertExitCode(0); } + #[Test] + public function it_uses_the_configured_queue_connection_by_default() + { + $index = $this->fakeIndex(); + $index->shouldReceive('onConnection')->never(); + $index->shouldReceive('onQueue')->never(); + + $this->artisan(Update::class, ['index' => 'test'])->assertExitCode(0); + } + + #[Test] + public function it_uses_the_queue_connection_from_the_connection_option() + { + $index = $this->fakeIndex(); + $index->shouldReceive('onConnection')->once()->with('sync')->andReturnSelf(); + + $this->artisan(Update::class, ['index' => 'test', '--connection' => 'sync'])->assertExitCode(0); + } + + #[Test] + public function it_uses_the_queue_from_the_queue_option() + { + $index = $this->fakeIndex(); + $index->shouldReceive('onQueue')->once()->with('indexing')->andReturnSelf(); + + $this->artisan(Update::class, ['index' => 'test', '--queue' => 'indexing'])->assertExitCode(0); + } + + #[Test] + public function it_uses_the_connection_and_queue_together() + { + $index = $this->fakeIndex(); + $index->shouldReceive('onConnection')->once()->with('redis')->andReturnSelf(); + $index->shouldReceive('onQueue')->once()->with('indexing')->andReturnSelf(); + + $this->artisan(Update::class, ['index' => 'test', '--connection' => 'redis', '--queue' => 'indexing'])->assertExitCode(0); + } + #[Test] public function it_errors_when_the_index_doesnt_exist() { diff --git a/tests/Search/IndexTests.php b/tests/Search/IndexTests.php index 24e8983d94b..5ce314b75c8 100644 --- a/tests/Search/IndexTests.php +++ b/tests/Search/IndexTests.php @@ -70,4 +70,34 @@ public function it_dispatches_the_insert_job_with_the_configured_handle_not_the_ fn (InsertMultipleJob $job) => $job->name === 'test' && $job->locale === 'en' ); } + + #[Test] + public function it_dispatches_the_insert_job_on_the_given_queue_connection() + { + Bus::fake(); + + $index = $this->getIndex('test', [], 'en'); + + $index->onConnection('sync')->insertMultiple(collect(['foo::bar'])); + + Bus::assertDispatched( + InsertMultipleJob::class, + fn (InsertMultipleJob $job) => $job->name === 'test' && $job->locale === 'en' && $job->connection === 'sync' + ); + } + + #[Test] + public function it_dispatches_the_insert_job_on_the_given_queue() + { + Bus::fake(); + + $index = $this->getIndex('test', [], 'en'); + + $index->onQueue('indexing')->insertMultiple(collect(['foo::bar'])); + + Bus::assertDispatched( + InsertMultipleJob::class, + fn (InsertMultipleJob $job) => $job->name === 'test' && $job->locale === 'en' && $job->queue === 'indexing' + ); + } }