Apa yang saya coba buat adalah sistem yang membaca/mengurai data dari lebih dari selusin situs web eksternal.
Sebagai contoh, katakanlah saya ingin membuat sistem yang mem-parsing postingan Twitter di halaman profil pengguna tertentu. Saya ingin melakukan ini untuk lebih dari selusin pengguna.
Selain itu, saya ingin pekerjaan terpisah berjalan untuk masing-masing pengguna ini. Jadi jika ada 12 pengguna, saya perlu 12 pekerjaan berjalan.
Ketika pekerjaan telah selesai (yaitu ketika semua posting pengguna di halaman telah diurai), saya memerlukan pekerjaan untuk memulai dari awal lagi (untuk mengurai posting baru).
Jadi pada akhirnya, jika ada 12 pengguna, saya harus memiliki 12 pekerjaan yang terus berjalan yang mengurai postingan baru yang dibuat oleh salah satu dari 12 pengguna ini.
Sejauh yang saya tahu, ada dua cara untuk melakukan ini. Yang pertama adalah menggunakan cron jobs, yang kedua adalah menggunakan sistem antrian.
Apa cara terbaik untuk mengatasi ini? Pekerjaan atau antrian cron? Bagaimana cara menerapkannya dengan benar?
Dengan cron jobs, dua masalah yang terpikir oleh saya adalah cron dijalankan berdasarkan waktu, bukan berdasarkan penyelesaian tugas, artinya jika suatu tugas selesai, ia harus menunggu hingga tugas cron dipanggil lagi (misalnya, setiap 5 menit). Masalah lainnya adalah tumpang tindih. Bagaimana jika suatu pekerjaan tidak selesai tepat waktu tetapi cron memanggil pekerjaan itu lagi?
Ini adalah versi sederhana dari implementasi pekerjaan antrean saya saat ini, namun saya perhatikan bahwa penggunaan CPU saya melonjak antara 75-90%:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Page;
class PageParser extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $page;
public function __construct(Page $page)
{
$this->page = $page;
}
public function handle()
{
// Parsing done here, removed for simplicity
$this->delete();
dispatch(new PageParser($this->page));
}
}