1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Jobs;
7
8use App\Libraries\Elasticsearch\Es;
9use App\Libraries\Elasticsearch\Indexable;
10use Exception;
11use Illuminate\Bus\Queueable;
12use Illuminate\Contracts\Queue\ShouldQueue;
13use Illuminate\Foundation\Bus\Dispatchable;
14use Illuminate\Queue\InteractsWithQueue;
15
16class EsIndexDocumentBulk implements ShouldQueue
17{
18 use Dispatchable, InteractsWithQueue, Queueable;
19
20 protected $className;
21 protected $ids;
22
23 public function __construct(string $className, array $ids)
24 {
25 if (!is_a($className, Indexable::class, true)) {
26 throw new Exception("{$className} is not indexable.");
27 }
28
29 $this->className = $className;
30 $this->ids = $ids;
31 }
32
33 public function handle()
34 {
35 $dummy = new $this->className();
36
37 $chunks = array_chunk($this->ids, Es::CHUNK_SIZE);
38 foreach ($chunks as $chunk) {
39 $models = $this->className::esIndexingQuery()->whereIn($dummy->getKeyName(), $chunk)->get();
40 $actions = Es::generateBulkActions($models);
41 if (!empty($actions)) {
42 // TODO: handling response would be nice =)
43 Es::getClient()->bulk([
44 'index' => $this->className::esIndexName(),
45 'body' => $actions,
46 'client' => ['timeout' => 0],
47 ]);
48 }
49 }
50 }
51}