Problem/Motivation
When running any CLI process that uses a semaphore (i.e.- drush cron
), if that process gets interrupted by a POSIX signal (usually SIGINT
triggered by Ctrl+C
), Drupal's shutdown function is not executed, leading to a stale semaphore. In the case of drush cron
, that means having to wait 15 minutes until the lock expires.
This is a recurring issue that has been causing trouble to lots of developers in the last years: https://drupal.stackexchange.com/questions/17264/cron-stopped-running-lo... and https://drupal.stackexchange.com/questions/203099/release-cron-lock
Steps to reproduce
On a POSIX compatible system:
- Run
drush cron
on a terminal
- While it's still executing, press
Ctrl+C
- Cron execution is stopped (shutdown function is not executed and the semaphore lock is not purged)
- Run
drush cron
again. It won't start, throwing a warning with this message: "Attempting to re-run cron while it is already running"
Proposed resolution
- Add a handler for POSIX signals, that handles when a process is stopped. I provide that handler (
Drupal\Component\Utility\SignalHandler
) with tests.
- Use that signal handler in
Drupal\Core\Lock\DatabaseLockBackend
to handle the following signals:
- SIGHUP
- SIGINT
- SIGQUIT
- SIGTERM
Given the fact that POSIX signals only work on POSIX systems (Linux, BSD and alike), Drupal\Component\Utility\SignalHandler
uses a very defensive approach, checking that the required PHP extensions are loaded (PCNTL and POSIX) and that the actual functions being used are also available (pcntl_signal()
, pcntl_signal_get_handler()
, etc)
Remaining tasks
None.
User interface changes
None.
API changes
No changes. A new utility (Drupal\Component\Utility\SignalHandler) is added
Data model changes
None.
Release notes snippet
Add a POSIX signal handler to avoid stale semaphores on CLI
When running any CLI process that uses a semaphore (i.e.- "drush cron"), if that process gets interrupted by a POSIX signal (usually "SIGINT" triggered by "Ctrl+C"), Drupal's shutdown function is not executed, leading to a stale semaphore. In the case of "drush cron", that means having to wait 15 minutes until the lock expires. This change adds a POSIX signal handler that can be used by any component or module, and makes use of it by the lock system to avoid stale semaphores.