Laravel 13.31 menambah tugasan yang boleh dihentikan (interruptible jobs), membolehkan pekerja queue menangkap isyarat SIGTERM yang dihantar semasa deployment dan menutup proses dengan kemas dan bukannya menghentikan tugasan di tengah jalan. Pasukan yang menjalankan tugasan yang lama—seperti memproses puluhan ribu baris, menghantar e-mel pukal, atau menjana laporan—akan mendapat manfaat kerana data kekal konsisten apabila versi baharu dilancarkan.
Mengapa deployment sering mematikan tugasan
Apabila versi baharu dilancarkan, pengurus proses seperti Supervisor, Docker, dan Kubernetes memberitahu pekerja sedia ada untuk berhenti dengan menghantar SIGTERM, iaitu permintaan sopan untuk menamatkan proses. Kebanyakan pekerja menunggu tugasan semasa selesai sebelum keluar. Masalah timbul apabila pengurus hanya memberikan beberapa saat untuk mematuhi arahan tersebut. Jika sesuatu tugasan memerlukan masa beberapa minit, pengurus akan meningkat kepada SIGKILL, yang mematikan proses secara serta-merta. Tugasan tersebut tidak akan mencapai keadaan yang konsisten, meninggalkan rekod yang dikemas kini secara separa, fail terbiar, atau kerja yang bertindih.
Jawapan Laravel: gangguan secara kerjasama (cooperative interruption)
Laravel 13.31 memperkenalkan kontrak bernama Interruptible yang boleh dilaksanakan oleh kelas tugasan untuk menyedari permintaan penamatan. Apabila SIGTERM tiba, Laravel memanggil kaedah interrupted() pada tugasan tersebut. Kerangka kerja ini tidak menghentikan tugasan secara automatik; tugasan tersebut mesti menyemak penanda (flag) yang ditetapkan oleh Laravel dan keluar dengan sendirinya. Model kerjasama ini membolehkan pembangun menyelesaikan iterasi gelung semasa, mengembalikan (roll back) perubahan separa, atau menulis titik semakan (checkpoint) sebelum berhenti.
Cara menjadikan tugasan boleh dihentikan
- Laksanakan kontrak – tambah
implements Interruptiblepada definisi kelas tugasan. - Semak penanda di dalam gelung kerja – masukkan semakan pada setiap iterasi untuk melihat sama ada tugasan perlu berhenti.
- Lakukan pembersihan – dalam
interrupted(), simpan sebarang keadaan (state) yang membolehkan tugasan disambung kemudian, atau log gangguan tersebut untuk analisis lanjut.
Perangkap terbesar: jangan gunakan --once
Menjalankan pekerja queue dengan php artisan queue:work --once akan menyahaktifkan pengendalian isyarat sepenuhnya. Pekerja tersebut memproses satu tugasan sahaja dan keluar, tetapi ia tidak pernah mendaftarkan pengendali (handler) SIGTERM. Akibatnya, sebarang tugasan yang boleh dihentikan akan mengabaikan permintaan penamatan dan dimatikan di tengah proses. Corak ini sering kelihatan dalam kontena yang dipacu cron dan deployment sekali jalan (one-shot). Atasi masalah ini dengan menjalankan mod daemon (php artisan queue:work) setiap kali anda memerlukan tugasan yang boleh dihentikan.
Memantau gangguan
Laravel mencetuskan dua acara (events) yang boleh anda sambungkan (hook into):
- WorkerInterrupted – dicetuskan setiap kali mana-mana pekerja menerima SIGTERM. Merekodkan acara ini memberikan pandangan peringkat tinggi tentang kekerapan deployment mengganggu pekerja.
- JobInterrupted – dicetuskan hanya jika tugasan semasa melaksanakan kontrak Interruptible. Gunakan acara ini untuk mencetuskan pembersihan khusus tugasan, seperti memadam fail sementara atau mengemas kini penanda "baris terakhir yang diproses".
Mendengar acara-acara ini membolehkan pasukan membina papan pemuka (dashboard) yang menunjukkan kesan deployment dan mengenal pasti tugasan yang kerap terhenti di tengah jalan.
Pelaporan saiz queue mendapat penambahbaikan
Rilisan ini menambah kaedah totalSize() kepada pengurus queue, yang mengembalikan jumlah keseluruhan tugasan tertunda merentasi semua queue. Nilai ini boleh dipercayai untuk pemandu (driver) berasaskan pangkalan data dan Redis, yang melaporkan jumlah sebenar. Pemandu seperti SQS, Sync, dan Beanstalkd masih mengembalikan sifar kerana ia tidak mendedahkan jumlah melalui API Laravel. Pasukan yang menggunakan SQS harus terus bergantung pada metrik CloudWatch untuk kedalaman queue (queue depth).
Apa maksudnya untuk tetapan yang berbeza
- Docker/Kubernetes – tempoh penutupan yang kemas (graceful shutdown) kini boleh digunakan dengan berkesan. Panjangkan tempoh ihsan penamatan supaya tugasan mempunyai beberapa saat untuk menyedari penanda dan keluar dengan kemas.
- Supervisor – tetapkan
stopwaitsecslebih tinggi daripada masa yang anda jangkakan untuk tugasan selesai selepas menerima penanda gangguan. - Tugasan lama (legacy) – semak sebarang tugasan yang berjalan lebih lama daripada masa tamat (timeout) pengurus dan, jika boleh, jadikannya boleh dihentikan.
Sudut pandangan berbeza: kerumitan tambahan
Ciri ini tidak menggantikan konfigurasi masa tamat (timeout) yang betul. Jika gelung tugasan tidak pernah menyemak penanda gangguan, pengurus akan tetap menghantar SIGKILL. Pasukan mesti mengaudit laluan kod yang berjalan lama dan memasukkan semakan pada titik henti (breakpoint) yang logik. Sesetengah pembangun mungkin mendapati kod boilerplate tambahan—melaksanakan kontrak dan menambah semakan penanda—kurang menarik untuk tugasan pendek yang sudah pun selesai dalam jendela penutupan.
Senarai semak tindakan
- Imbas skrip deployment untuk bendera
--oncedan gantikan ia dengan mod daemon di mana tugasan yang boleh dihentikan (interruptible jobs) digunakan. - Kenal pasti tugasan yang berjalan paling lama (yang melibatkan puluhan ribu baris atau berjalan selama beberapa minit) dan tambah kontrak Interruptible.
- Masukkan semakan bendera di dalam setiap iterasi gelung, dan pindahkan sebarang kod pemuktamadan yang diperlukan ke dalam kaedah
interrupted(). - Sambungkan pendengar (listeners) kepada
WorkerInterrupteddanJobInterrupteduntuk mengumpul metrik tentang kekerapan deployment menjejaskan pemprosesan. - Untuk barisan Redis atau pangkalan data, gunakan
totalSize()untuk memantau tunggakan; untuk SQS, kekalkan penggera CloudWatch.
Anggap penutupan yang didorong oleh deployment sebagai satu langkah yang terkoordinasi dan bukannya pemberhentian secara mengejut. Laravel 13.31 mengekalkan konsistensi data dan memudahkan kerumitan operasi tugasan yang tidak selesai sepenuhnya. Imbalannya adalah peningkatan kecil dalam tanggungjawab kod, tetapi pasukan yang bergantung kepada pemprosesan latar belakang yang berat akan mendapat persekitaran pengeluaran yang lebih dipercayai.
