Gracefully stop PHP process with PCNTL

เวลาเขียน process ไรสักอย่างด้วย PHP ที่ใส่ loop ไว้เพื่อให้มันทำงานไปตลอดจนกว่าจะโดน kill เราสามารถใช้ PCNTL เพื่อให้ script PHP รู้ว่ามีคนขอ ให้ process หยุดทำงานได้แล้ว ถ้ามีงานที่ทำต่อเนื่องอยู่ยังไม่ถึง checkpoint จะได้มีโอกาสทำต่อให้เสร็จก่อน และก็ exit; ตัวเองซะ ไม่ต้องไปทำ task ต่อไป.

ตัวอย่าง code

<?php
$running = true;

function signal_listener ($signo) {
  global $running;
  $running = false;
}

declare(ticks=1); // Changelog version 4.3.0 สั่งให้ทำ

// เราจะดักสัญญาณ 4 ตัวนี้ เพื่อสั่งให้เลิก loop
pcntl_signal(SIGTERM, 'signal_listener');
pcntl_signal(SIGINT,  'signal_listener');
pcntl_signal(SIGHUP,  'signal_listener');
pcntl_signal(SIGUSR1, 'signal_listener');

while ($running) {
  // executing task...
}

มันมี signal หลายตัวเลย ไม่ได้หาข้อมูลละเอียดเหมือนกัน แต่จับ 4 ตัวนี้ก็น่าจะครอบคลุมแล้ว. เบื้องต้นก็ประมาณนี้

  • SIGTERM พวกตัวคุม process อย่าง daemon หรือ supervisor เวลาที่เราสั่ง stop มันจะส่ง SIGTERM เนี่ยแหละไปให้ process
  • SIGINT เวลาที่เรารันคำสั่งใน terminal แล้วกด Ctrl+C (^C) ตัวนี้มันจะส่ง SIGINT ไปยัง process ที่เรากำลังรัน

ที่เหลือไป Google เพิ่มเติมแล้วกัน.

Composer

ถ้าใช้ PCNTL ใน project ที่ใช้ composer อย่างตัว PHPStorm มันก็จะเตือนว่า ใน composer.json ไม่มี ext-pcntl ซึ่งถ้าเราเติมอันนี้ไว้ใน composer.json เวลาที่สั่ง composer install หรือ update บน OS Windows มันจะพัง เพราะว่า Windows ไม่รองรับ PCNTL. เพื่อให้เราสามารถรันคำสั่ง composer ได้ ให้เติม ignore-platform-reqs เข้าไปด้วย แบบนี้

$ composer install --ignore-platform-reqs

Manual:
https://www.php.net/manual/en/book.pcntl.php

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.