Pekerjaan yang dimulai kembali setelah selesai?

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));
    }
}

person user6605184    schedule 18.07.2016    source sumber
comment
Apakah Anda benar-benar mencari postingan Twitter? Jika demikian, Anda harus melihat titik akhir streamingnya. Membuat pekerjaan yang tidak pernah berakhir akan cukup mudah dengan menggunakan perulangan while berdasarkan status koneksi   -  person ExoticChimp    schedule 19.07.2016
comment
Tidak, saya tidak mencari postingan Twitter. Contoh saya adalah penyederhanaan gagasan umum.   -  person user6605184    schedule 19.07.2016


Jawaban (2)


Saya belum mencobanya, tapi saya berasumsi Anda bisa membuat pekerjaan rekursif.

Pekerjaan rekursif ini akan mengeksekusi semua kode yang diperlukan, kemudian, di akhir eksekusi, pekerjaan baru akan dibuat dan dimasukkan ke dalam antrean - yang kemudian akan mulai berjalan segera setelah antrean siap untuk itu.

Jika suatu pekerjaan gagal, Anda tidak akan membuat pekerjaan baru, sehingga Anda tidak akan menjalankan pekerjaan pengguna yang sama secara bersamaan. Pekerjaan yang gagal akan dicoba lagi - dan bila berhasil, akan menciptakan pekerjaan baru.

person swatkins    schedule 18.07.2016

Anda bisa menggunakan kombinasi. Buat perintah seperti 'RetrieveDataCommand' atau apa pun. Perintah ini harus memasukkan pekerjaan ke dalam antrian untuk setiap pengguna yang akan mengambil data untuk pengguna tersebut (dan mungkin pekerjaan terpisah untuk benar-benar diproses jika diperlukan?). Pekerjaan tersebut harus memperhitungkan parameter '$from' yang merupakan cap waktu jika perintah 'sebelumnya' dijalankan. Saat dijalankan, ia mengambil semua data untuk semua pengguna untuk jangka waktu $dari hingga sekarang().

Anda kemudian dapat meminta tugas cron menjalankan perintah setiap 10 detik atau apa pun. $from dapat dihitung dengan menyimpan (dalam cache/DB/sesuatu yang semi persisten) cap waktu dari waktu saat ini segera setelah perintah dijalankan oleh cron sehingga perintah berikutnya dapat mencarinya ketika dijalankan dan kemudian menimpanya untuk proses berikutnya. Atau lakukan saja now() dikurangi interval cron meskipun itu kurang fleksibel.

Anda kemudian dapat menghapus penghapusan mandiri dan mengirimkan barang dari pekerjaan Anda

person ExoticChimp    schedule 18.07.2016