magento / community-features

Magento Features Development is an Initiative to Allows Community Memebers Join to Development of Magento Features
46 stars 18 forks source link

Allow handling POSIX signals (ie. SIGTERM for graceful termination) #280

Open michael-bouvy opened 4 years ago

michael-bouvy commented 4 years ago

ℹ️ Copied from https://github.com/magento/magento2/issues/28870 as requested by @engcom-Lima

Description (*)

Magento is currently not able to handle POSIX signals, for instance SIGTERM that may be received from a controller (ie. within Kubernetes cluster).

Therefore, those signals can not be handled gracefully, and the process may be killed with a SIGKILL signal, causing an immediate stop, without calling __destruct methods for instance.

Expected behavior (*)

Since PHP 7.1, signals can be received without overhead using the pcntl_async_signals(true) function call.

Signals can subsequently be handled using something like:

pcntl_signal(SIGTERM, function () {
    // Do something that will cause graceful shutdown of process
});

Calling the exit() PHP function within this handler causes the __destruct class methods to be called, which is desirable.

Example script

`<magento-root>/signal.php`
<?php
use Magento\Framework\App\Bootstrap;

require __DIR__ . '/app/bootstrap.php';

$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$resourceConnection = $objectManager->create('Magento\Framework\App\ResourceConnection');

class Signal
{
    public function run()
    {
        while (true) {
            echo date('Y-m-d H:i:s') . PHP_EOL;
            sleep(1);
        }
    }

    public function __destruct()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

pcntl_async_signals(true);

pcntl_signal(SIGTERM, function () {
    echo 'Caught SIGTERM' . PHP_EOL;
    exit(1);
});

(new Signal())->run();

When sending a SIGTERM signal to the process, we get the following output:

$ php signal.php
2020-06-24 11:06:11
Caught SIGTERM
Signal::__destruct

ℹ️ Without these pcntl_* functions, the script runs indefinitely, until killed with a SIGKILL signal.

Magento should therefore call pcntl_async_signals(true), at least for cron and consumers.

Benefits

Such signal handling would be useful to handle graceful termination of long-running processes (cron, consumers): process current message and exit, close database connection, etc.

For consumers, this achieves the same goal as poison pill, but with an immediate effect, not requiring to wait for the message to be processed.

Additional information

m2-assistant[bot] commented 4 years ago

Hi @michael-bouvy. Thank you for your report. To help us process this issue please make sure that you provided sufficient information.

Please, add a comment to assign the issue: @magento I am working on this


sivaschenko commented 3 years ago

Hi @michael-bouvy thanks for the report!

Are there any sensible issues resulting from the current behaviour? Do you have a specific proposal on how such handling should be implemented in the Magento codebase?

michael-bouvy commented 3 years ago

Hi @sivaschenko, I guess the following may be used as an inspiration: https://symfony.com/blog/new-in-symfony-5-2-console-signals

jonathanribas commented 1 year ago

Hi @sivaschenko,

Any update on this topic? It's been almost 3 years it's open now :(

Thanks in advance!