friendica/src/Core/Worker/Daemon.php

136 lines
3.1 KiB
PHP

<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Core\Worker;
use Friendica\App\Mode;
use Friendica\Core\Logger;
use Friendica\DI;
/**
* Contains the class for the worker background job processing
*/
class Daemon
{
private static $mode = null;
/**
* Checks if the worker is running in the daemon mode.
*
* @return boolean
*/
public static function isMode()
{
if (!is_null(self::$mode)) {
return self::$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::$mode = false;
return false;
}
$pidfile = DI::config()->get('system', 'pidfile');
if (empty($pidfile)) {
// No pid file, no daemon
self::$mode = false;
return false;
}
if (!is_readable($pidfile)) {
// No pid file. We assume that the daemon had been intentionally stopped.
self::$mode = false;
return false;
}
$pid = intval(file_get_contents($pidfile));
$running = posix_kill($pid, 0);
self::$mode = $running;
return $running;
}
/**
* Test if the daemon is running. If not, it will be started
*
* @return void
*/
public static function checkState()
{
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::spawn();
}
/**
* Spawn a new daemon process
*
* @return void
*/
private static function spawn()
{
Logger::notice('Starting new daemon process');
DI::system()->run('bin/daemon.php', ['start']);
Logger::notice('New daemon process started');
}
}