Membuat Queue sederhana dengan Database pada Laravel

Queue adalah salah satu teknik agar proses pada aplikasi kita dapat berjalan secara mengantri. Kenapa dibuat mengantri? kadang beberapa proses dilakukan sesuai dengan antrian sehingga berjalan sesuai flow yang direncanakan.

Pada laravel, proses queue sudah sangat mudah dilakukan. Pada artikel ini saya coba jelaskan contoh simple membuat queue pada proses tertentu. Diharapkan dengan membaca artikel ini, pembaca mengetahui proses kerja queue dengan database pada Laravel. Untuk production, saya sarankan untuk menggunakan redis atau amazon sqs atau driver lainnya yang lebih baik dari database.

# Langkah 1
Membuat proyek laravel, saat artikel ini dibuat, saya menggunakan Laravel 5.5 LTS. Jika dikemudian hari laravel sudah berubah, mohon disesuaikan dengan dokumentasi. Saya membuat folder laravel-jobtable

# Langkah 2
Setelah kita menginstall laravel 5.5, kita buat database pada mysql local kita. Pada artikel ini saya buat “laravel-jobtable”.

# Langkah 3
Setelah membuat database tersebut, kita sesuaikan di konfigurasi laravel dengan mysql database di file .env

# Langkah 4
Setelah langkah ketiga telah dilakukan, mari kita coba jalankan proses migration untuk menyimpan queue laravel pada database dengan cara mengetikan pada terminal seperti pada gambar dibawah ini.

php artisan queue:job
php artisan queue:job

Setelah berhasil lanjutkan dengan php artisan migrate.

migrate job success
migrate job success

Setelah berhasil, cek database kita. Apa benar database sudah terinstall table-table yang telah berhasil di migrate.

tables current
tables current

Lalu kita lihat ada table jobs, data masih kosong dan struktur seperti gambar dibawah ini.

empty jobs
empty jobs

Nanti table jobs inilah yang berisi queue/atrian yang akan kita jalankan pada proyek laravel kita. Lanjut ke langkah berikutnya ya.

# Langkah 5
Pada langkah ini, mari kita coba membuat dua proses untuk melakukan atrian. Proses ini saya sebut juga job. Pada laravel, kita dapat mudah mengetikan perintah “php artisan make:job “. Pada artikel ini saya buat JobPertama dan JobKedua sebagai percobaan.

laravel job pertama dan kedua
laravel job pertama dan kedua

Baik, mari kita edit kedua job tersebut. File kedua job tersebut berada pada folder /app/Jobs/.

Lalu saya coba menuliskan job untuk write log untuk melihat apakah benar job tersebut berjalan sesuai yang diharapkan atau tidak.

File /app/Jobs/JobPertama.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use Log;

class JobPertama implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('Ini log dari JobPertama dengan data ' . $this->data);
    }
}

 

File /app/Jobs/JobKedua.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use Log;

class JobKedua implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('Ini log dari JobKedua dengan data ' . $this->data);
    }
}

Pada kedua job tersebut, saya menambakan Log untuk menuliskan log dari job yang telah kita buat. Ada flag darimana log tersebut dibuat sehingga kita bisa mengetahui apa benar proses sesuai dengan yang kita harapkan?

# Langkah 6

Setelah kita buat job, saatnya kita panggil job tersebut. Job akan berjalan sesuai dengan antrian/queue yang telah kita buat. Cara panggilnya mudah, kita buka controller atau lokasi yang ingin menggunakan job pertama dan job kedua ini lalu sisipkan kode seperti pada contoh ini.

Sebelumnya kita buat dulu controller dengan nama misalnya HomeController. Karana default laravel 5.5 belum ada controllernya.

Berikut kode dari HomeController.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\JobPertama;
use App\Jobs\JobKedua;

class HomeController extends Controller
{
    public function index() {

        JobPertama::dispatch('belajar queue dengan');
        JobKedua::dispatch('laravel');

        return "berhasil";

    }
}

Pada HomeController itu kita include JobPertama dan JobKedua, lalu kita panggil dengan <namajob>::dispatch(<data yang ingin dilempar ke job>).

Data yang ingin dilempar ke job itu nanti di handle di construct method job tersebut. Dan prosesnya ada di method handle 🙂

Setelah itu mari kita panggil HomeController tersebut dengan menyetting route web ‘/’ mengarah ke HomeController method index.

Langkah 7:

Setelah itu, jangan lupa file .env terdapat konfigurasi untuk menyetting driver queue yang ingin kita gunakan. Defaultnya laravel menggunakan sync. Ganti QUEUE_DRIVER=sync menjadi QUEUE_DRIVER=database.

Langkah 8:

Jalankan artisan serve 🙂 lalu lihat pada /storage/logs/laravel.log.

Jika selesai halaman akan memunculkan “berhasil”. Apakah ada data yang tersimpan pada log? Dan saat itu juga, mari kita lihat database table jobs. Apakah ada perubahan atau tidak ya?

Yap ada data ya

job menunggu perintah
job menunggu perintah

Pada gambar diatas terlihat ada 2 job yang tersimpan. Pada table tersebut adalah list dari job yang akan dijalankan oleh laravel. Karena kita belum memanggil satu fungsi untuk menjalankan job tersebut. Maka job tersebut akan terlist pada table tersebut.

Mari kita coba jalankan perintah untuk memanggil job dengan perintah “php artisan queue:work”.

Lalu sekarang cek kembali table jobs tersebut. Sudah hilang ya data-datanya. Itu karena data jobs telah terpanggil untuk dijalankan. Sekarang coba lihat file /storage/logs/laravel.log.

hasil log queue

Yap, sekarang sudah ada log nya yaa..

Begitulah kira-kira cara kerja job queue.

  • Kita buat job
  • Dijalankan HomeController
  • Proses di HomeController hanya untuk menuliskan job ke table jobs
  • Setelah HomeController berhasil menuliskan job tersebut. Proses HomeController selesai.
  • JobPertama dan JobKedua dijalankan oleh laravel queue:work dengan membaca table jobs tersebut di background proses.
  • Jadi ada 2 proses, proses di HomeController dan proses di background

Coba kita bayangkan ada proses pengiriman email pada HomeController. Dimana pengiriman email tersebut belum menggunakan job.

  • Jalankan HomeController
  • Jalankan proses yang ada HomeController salah satunya adalah pengiriman email.
  • Waktu pengiriman email kisaran 3-5 detik tergantung dengan koneksi
  • Sampai pengiriman email berhasil, HomeController berhasil dipanggil
  • Jadi ada proses dan waktu menunggu pengiriman email dari proses HomeController tersebut.

Jika kita buat job dalam pengiriman email akan lebih simpel karena proses di HomeController hanya menyimpan job pengiriman email ke table jobs. Sedangkan proses pengiriman email dilakukan di background (secara terpisah). Sehingga tidak memakan waktu yang lama.

Pada proses ini tidak terlihat, silahkan coba buat job untuk pengiriman email ke mailtrap.io untuk mencoba.

2 comments

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: