Bài viết này vừa viết để share và cũng là để mình nắm rõ, chi tiết hơn về món này.
Thật ra món này mình đã xài trên XGallery – Symfony rồi. Tuy nhiên trên Laravel version thì nó được supported sẵn và chỉnh chu hơn rất nhiều. Let’ check it !
Queues là 1 một hàng đợi để từ đó dần dần thực thi.
Có thể handle số lượng worker tham gia xử lý
Đặc trưng của queue
Có thể tách ra worker trên nhiều server. Mỗi server handle 1 loại worker
Nếu worker xử lý failed. Queue sẽ được đưa vào failed_jobs và sau đó retry lại
$items->each(function ($item, $key) {
$this->progressBar->setMessage($item['title'], 'info');
// Item process
$model = app(\App\Onejav::class);
if ($model->where(['url' => $item['url']])->first()) {
$this->progressBar->setMessage($key+1, 'step');
return;
}
// Convert to Mongo DateTime
$item['date'] = new UTCDateTime($item['date']->getTimestamp() * 1000);
$model->insert($item);
// Trigger job to process idols & related data
UpdateJavIdols::dispatch($item)->onConnection('database');
UpdateJavGenres::dispatch($item)->onConnection('database');
$this->progressBar->setMessage($key+1, 'step');
});
Mình có 1 con Command line trên. Nhiệm vụ nó là fetch data detail của 1 film JAV nào đó và save vào database. Ở đây xài Mongo.
Con crawler trên trả về data 1 film trên OneJAV. Trong đó có
- Tên film
- Idols
- Genres
- Torrent
Vậy lúc này queues sẽ có ý nghĩa gì
- Update idols vào database. Việc update này song song với việc lấy data từ XCity để lấy đủ profile em nó. Ví dụ như số đo 3 vòng, tuổi …
- Update genres vào database
Đúng là ta cũng có thể làm việc đó ngay trên Command này. Tuy nhiên vô tình làm nặng process này. Cộng với tính “logic” của Command mất đi. ( Vì nó được sử dụng chỉ thuần tuý lấy data OneJAV và save thôi ). Do đó cần dispatch queues riêng cho việc này.
Và hơn nữa. Giả sử việc lấy data của 2 con queues bị failed vì bất kì lý do gì. Thì cần try again ! Xử lý chung 1 Command rất waste resources !
UpdateJavIdols::dispatch($item)->onConnection('database');
UpdateJavGenres::dispatch($item)->onConnection('database');
Như vậy nghĩa là Command này chỉ việc trigger 2 jobs trên. Và nó xong. Còn lại worker sẽ tự lấy queues ra xử lý tiếp.
Con UpdateJavIdols sẽ có đoạn code sau
public function handle()
{
$crawler = app(XCityProfile::class);
foreach ($this->itemDetail['actresses'] as $actress) {
$actresses = $crawler->search(['genre' => 'idol', 'q' => $actress, 'sg' => 'idol']);
$actresses->each(function ($actresses) {
$actresses->each(function ($actress) {
$actressDetail = app(XCityProfile::class)
->getItemDetail('https://xxx.xcity.jp/idol/'.$actress['url']);
$model = app(JavIdols::class);
if ($model->where(['reference_url' => $actressDetail->url])->first()) {
return;
}
$model->name = $actressDetail->name;
$model->reference_url = $actressDetail->url;
$model->cover = $actressDetail->cover;
$model->favorite = $actressDetail->favorite ?? null;
$model->birthday = $actressDetail->birthday ?? null;
$model->blood_type = $actressDetail->blood_type ?? null;
$model->city = $actressDetail->city ?? null;
$model->height = $actressDetail->height ?? null;
$model->breast = $actressDetail->breast ?? null;
$model->waist = $actressDetail->waist ?? null;
$model->hips = $actressDetail->hips ?? null;
$model->save();
unset($model);
});
});
}
}
Nếu vì bất kì lý do gì failed ( gây ra bởi fatal error nhe !!! ) thì nó sẽ được đưa vào failed_jobs và retry lại sau.
Chi tiết hơn về queues sẽ update tiếp ở bài sau.
Leave a Reply