- /**
- * Set the flag if some job is waiting
- *
- * @param boolean $jobs Is there a waiting job?
- * @param int $key Key number
- * @throws \Exception
- */
- public static function IPCSetJobState(bool $jobs, int $key = 0)
- {
- $stamp = (float)microtime(true);
- DBA::replace('worker-ipc', ['jobs' => $jobs, 'key' => $key]);
- self::$db_duration += (microtime(true) - $stamp);
- self::$db_duration_write += (microtime(true) - $stamp);
- }
-
- /**
- * Delete a key entry
- *
- * @param int $key Key number
- * @throws \Exception
- */
- public static function IPCDeleteJobState(int $key)
- {
- $stamp = (float)microtime(true);
- DBA::delete('worker-ipc', ['key' => $key]);
- self::$db_duration += (microtime(true) - $stamp);
- self::$db_duration_write += (microtime(true) - $stamp);
- }
-
- /**
- * Checks if some worker job waits to be executed
- *
- * @param int $key Key number
- * @return bool
- * @throws \Exception
- */
- public static function IPCJobsExists(int $key = 0)
- {
- $stamp = (float)microtime(true);
- $row = DBA::selectFirst('worker-ipc', ['jobs'], ['key' => $key]);
- self::$db_duration += (microtime(true) - $stamp);
-
- // When we don't have a row, no job is running
- if (!DBA::isResult($row)) {
- return false;
- }
-
- return (bool)$row['jobs'];
- }
-
- /**
- * Checks if the worker is running in the daemon mode.
- *
- * @return boolean
- */
- public static function isDaemonMode()
- {
- if (!is_null(self::$daemon_mode)) {
- return self::$daemon_mode;
- }
-
- if (DI::mode()->getExecutor() == Mode::DAEMON) {
- return true;
- }
-
- $daemon_mode = DI::config()->get('system', 'worker_daemon_mode', false, true);
- if ($daemon_mode) {
- return $daemon_mode;
- }
-
- if (!function_exists('pcntl_fork')) {
- self::$daemon_mode = false;
- return false;
- }
-
- $pidfile = DI::config()->get('system', 'pidfile');
- if (empty($pidfile)) {
- // No pid file, no daemon
- self::$daemon_mode = false;
- return false;
- }
-
- if (!is_readable($pidfile)) {
- // No pid file. We assume that the daemon had been intentionally stopped.
- self::$daemon_mode = false;
- return false;
- }
-
- $pid = intval(file_get_contents($pidfile));
- $running = posix_kill($pid, 0);
-
- self::$daemon_mode = $running;
- return $running;
- }
-
- /**
- * Test if the daemon is running. If not, it will be started
- *
- * @return void
- */
- private static function checkDaemonState()
- {
- if (!DI::config()->get('system', 'daemon_watchdog', false)) {
- return;
- }
-
- if (!DI::mode()->isNormal()) {
- return;
- }
-
- // Check every minute if the daemon is running
- if (DI::config()->get('system', 'last_daemon_check', 0) + 60 > time()) {
- return;
- }
-
- DI::config()->set('system', 'last_daemon_check', time());
-
- $pidfile = DI::config()->get('system', 'pidfile');
- if (empty($pidfile)) {
- // No pid file, no daemon
- return;
- }
-
- if (!is_readable($pidfile)) {
- // No pid file. We assume that the daemon had been intentionally stopped.
- return;
- }
-
- $pid = intval(file_get_contents($pidfile));
- if (posix_kill($pid, 0)) {
- Logger::info('Daemon process is running', ['pid' => $pid]);
- return;
- }
-
- Logger::warning('Daemon process is not running', ['pid' => $pid]);
-
- self::spawnDaemon();
- }
-
- /**
- * Spawn a new daemon process
- *
- * @return void
- */
- private static function spawnDaemon()
- {
- Logger::notice('Starting new daemon process');
- $command = 'bin/daemon.php';
- $a = DI::app();
- DI::system()->run($command, ['start']);
- Logger::notice('New daemon process started');
- }
-