]> git.mxchange.org Git - friendica.git/blobdiff - src/Core/Worker.php
Convert potential spaces in Memcache(d) key names
[friendica.git] / src / Core / Worker.php
index 5bd281638f30b39072cba09a7fa9973b7d45f0ca..62fd321c24b6a32d0800dac49979ebdea5ed765a 100644 (file)
@@ -21,7 +21,6 @@
 
 namespace Friendica\Core;
 
-use Friendica\App\Mode;
 use Friendica\Core\Worker\Entity\Process;
 use Friendica\Database\DBA;
 use Friendica\DI;
@@ -50,7 +49,6 @@ class Worker
        private static $lock_duration = 0;
        private static $last_update;
        private static $state;
-       private static $daemon_mode = null;
        /** @var Process */
        private static $process;
 
@@ -62,7 +60,7 @@ class Worker
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function processQueue($run_cron, Process $process)
+       public static function processQueue(bool $run_cron, Process $process)
        {
                self::$up_start = microtime(true);
 
@@ -79,7 +77,7 @@ class Worker
                $last_cleanup = DI::config()->get('system', 'worker_last_cleaned', 0);
                if (time() > ($last_cleanup + 300)) {
                        DI::config()->set('system', 'worker_last_cleaned', time());
-                       self::killStaleWorkers();
+                       Worker\Cron::killStaleWorkers();
                }
 
                // Check if the system is ready
@@ -89,7 +87,7 @@ class Worker
 
                // Now we start additional cron processes if we should do so
                if ($run_cron) {
-                       self::runCron();
+                       Worker\Cron::run();
                }
 
                $last_check = $starttime = time();
@@ -97,15 +95,13 @@ class Worker
 
                // We fetch the next queue entry that is about to be executed
                while ($r = self::workerProcess()) {
-                       if (self::IPCJobsExists(getmypid())) {
-                               self::IPCDeleteJobState(getmypid());
+                       if (Worker\IPC::JobsExists(getmypid())) {
+                               Worker\IPC::DeleteJobState(getmypid());
                        }
 
                        // Don't refetch when a worker fetches tasks for multiple workers
                        $refetched = DI::config()->get('system', 'worker_multiple_fetch');
                        foreach ($r as $entry) {
-                               $entry = self::checkPriority($entry);
-
                                // The work will be done
                                if (!self::execute($entry)) {
                                        Logger::notice('Process execution failed, quitting.');
@@ -150,8 +146,8 @@ class Worker
                        if (time() > ($starttime + (DI::config()->get('system', 'cron_interval') * 60))) {
                                Logger::info('Process lifetime reached, respawning.');
                                self::unclaimProcess($process);
-                               if (self::isDaemonMode()) {
-                                       self::IPCSetJobState(true);
+                               if (Worker\Daemon::isMode()) {
+                                       Worker\IPC::SetJobState(true);
                                } else {
                                        self::spawnWorker();
                                }
@@ -160,30 +156,12 @@ class Worker
                }
 
                // Cleaning up. Possibly not needed, but it doesn't harm anything.
-               if (self::isDaemonMode()) {
-                       self::IPCSetJobState(false);
+               if (Worker\Daemon::isMode()) {
+                       Worker\IPC::SetJobState(false);
                }
                Logger::info("Couldn't select a workerqueue entry, quitting process", ['pid' => getmypid()]);
        }
 
-       /**
-        * Check and fix the priority of a worker task
-        * @param array $entry 
-        * @return array 
-        */
-       private static function checkPriority(array $entry)
-       {
-               $entry['priority'] = (int)$entry['priority'];
-
-               if (!in_array($entry['priority'], PRIORITIES)) {
-                       Logger::warning('Invalid priority', ['entry' => $entry, 'callstack' => System::callstack(20)]);
-                       DBA::update('workerqueue', ['priority' => PRIORITY_MEDIUM], ['id' => $entry['id']]);                    
-                       $entry['priority'] = PRIORITY_MEDIUM;
-               }
-
-               return $entry;
-       }
-
        /**
         * Checks if the system is ready.
         *
@@ -191,7 +169,7 @@ class Worker
         *
         * @return boolean
         */
-       public static function isReady()
+       public static function isReady(): bool
        {
                // Count active workers and compare them with a maximum value that depends on the load
                if (self::tooMuchWorkers()) {
@@ -226,7 +204,7 @@ class Worker
         * @return boolean Returns "true" if tasks are existing
         * @throws \Exception
         */
-       public static function entriesExists()
+       public static function entriesExists(): bool
        {
                $stamp = (float)microtime(true);
                $exists = DBA::exists('workerqueue', ["NOT `done` AND `pid` = 0 AND `next_try` < ?", DateTimeFormat::utcNow()]);
@@ -240,7 +218,7 @@ class Worker
         * @return integer Number of deferred entries in the worker queue
         * @throws \Exception
         */
-       private static function deferredEntries()
+       private static function deferredEntries(): int
        {
                $stamp = (float)microtime(true);
                $count = DBA::count('workerqueue', ["NOT `done` AND `pid` = 0 AND `retrial` > ?", 0]);
@@ -255,7 +233,7 @@ class Worker
         * @return integer Number of non executed entries in the worker queue
         * @throws \Exception
         */
-       private static function totalEntries()
+       private static function totalEntries(): int
        {
                $stamp = (float)microtime(true);
                $count = DBA::count('workerqueue', ['done' => false, 'pid' => 0]);
@@ -270,7 +248,7 @@ class Worker
         * @return integer Number of active worker processes
         * @throws \Exception
         */
-       private static function highestPriority()
+       private static function highestPriority(): int
        {
                $stamp = (float)microtime(true);
                $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()];
@@ -291,7 +269,7 @@ class Worker
         * @return integer Is there a process running with that priority?
         * @throws \Exception
         */
-       private static function processWithPriorityActive($priority)
+       private static function processWithPriorityActive(int $priority): int
        {
                $condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority];
                return DBA::exists('workerqueue', $condition);
@@ -300,41 +278,41 @@ class Worker
        /**
         * Checks if the given file is valid to be included
         *
-        * @param mixed $file 
-        * @return bool 
+        * @param mixed $file
+        * @return bool
         */
-       private static function validateInclude(&$file)
+       private static function validateInclude(&$file): bool
        {
                $orig_file = $file;
-       
+
                $file = realpath($file);
-       
+
                if (strpos($file, getcwd()) !== 0) {
                        return false;
                }
-       
+
                $file = str_replace(getcwd() . "/", "", $file, $count);
                if ($count != 1) {
                        return false;
                }
-       
+
                if ($orig_file !== $file) {
                        return false;
                }
-       
+
                $valid = false;
                if (strpos($file, "include/") === 0) {
                        $valid = true;
                }
-       
+
                if (strpos($file, "addon/") === 0) {
                        $valid = true;
                }
-       
+
                // Simply return flag
                return $valid;
        }
-       
+
        /**
         * Execute a worker entry
         *
@@ -343,7 +321,7 @@ class Worker
         * @return boolean "true" if further processing should be stopped
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function execute($queue)
+       public static function execute(array $queue): bool
        {
                $mypid = getmypid();
 
@@ -476,7 +454,7 @@ class Worker
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private static function execFunction($queue, $funcname, $argv, $method_call)
+       private static function execFunction(array $queue, string $funcname, array $argv, bool $method_call)
        {
                $a = DI::app();
 
@@ -565,7 +543,7 @@ class Worker
         * @return bool Are more than 3/4 of the maximum connections used?
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private static function maxConnectionsReached()
+       private static function maxConnectionsReached(): bool
        {
                // Fetch the max value from the config. This is needed when the system cannot detect the correct value by itself.
                $max = DI::config()->get("system", "max_connections");
@@ -642,85 +620,6 @@ class Worker
                return true;
        }
 
-       /**
-        * fix the queue entry if the worker process died
-        *
-        * @return void
-        * @throws \Exception
-        */
-       private static function killStaleWorkers()
-       {
-               $stamp = (float)microtime(true);
-               $entries = DBA::select(
-                       'workerqueue',
-                       ['id', 'pid', 'executed', 'priority', 'command', 'parameter'],
-                       ['NOT `done` AND `pid` != 0'],
-                       ['order' => ['priority', 'retrial', 'created']]
-               );
-               self::$db_duration += (microtime(true) - $stamp);
-
-               while ($entry = DBA::fetch($entries)) {
-                       $entry = self::checkPriority($entry);
-
-                       if (!posix_kill($entry["pid"], 0)) {
-                               $stamp = (float)microtime(true);
-                               DBA::update(
-                                       'workerqueue',
-                                       ['executed' => DBA::NULL_DATETIME, 'pid' => 0],
-                                       ['id' => $entry["id"]]
-                               );
-                               self::$db_duration += (microtime(true) - $stamp);
-                               self::$db_duration_write += (microtime(true) - $stamp);
-                       } else {
-                               // Kill long running processes
-
-                               // Define the maximum durations
-                               $max_duration_defaults = [PRIORITY_CRITICAL => 720, PRIORITY_HIGH => 10, PRIORITY_MEDIUM => 60, PRIORITY_LOW => 180, PRIORITY_NEGLIGIBLE => 720];
-                               $max_duration = $max_duration_defaults[$entry['priority']];
-
-                               $argv = json_decode($entry['parameter'], true);
-                               if (!empty($entry['command'])) {
-                                       $command = $entry['command'];
-                               } elseif (!empty($argv)) {
-                                       $command = array_shift($argv);
-                               } else {
-                                       return;
-                               }
-
-                               $command = basename($command);
-
-                               // How long is the process already running?
-                               $duration = (time() - strtotime($entry["executed"])) / 60;
-                               if ($duration > $max_duration) {
-                                       Logger::notice('Worker process took too much time - killed', ['duration' => number_format($duration, 3), 'max' => $max_duration, 'id' => $entry["id"], 'pid' => $entry["pid"], 'command' => $command]);
-                                       posix_kill($entry["pid"], SIGTERM);
-
-                                       // We killed the stale process.
-                                       // To avoid a blocking situation we reschedule the process at the beginning of the queue.
-                                       // Additionally we are lowering the priority. (But not PRIORITY_CRITICAL)
-                                       $new_priority = $entry['priority'];
-                                       if ($entry['priority'] == PRIORITY_HIGH) {
-                                               $new_priority = PRIORITY_MEDIUM;
-                                       } elseif ($entry['priority'] == PRIORITY_MEDIUM) {
-                                               $new_priority = PRIORITY_LOW;
-                                       } elseif ($entry['priority'] != PRIORITY_CRITICAL) {
-                                               $new_priority = PRIORITY_NEGLIGIBLE;
-                                       }
-                                       $stamp = (float)microtime(true);
-                                       DBA::update(
-                                               'workerqueue',
-                                               ['executed' => DBA::NULL_DATETIME, 'created' => DateTimeFormat::utcNow(), 'priority' => $new_priority, 'pid' => 0],
-                                               ['id' => $entry["id"]]
-                                       );
-                                       self::$db_duration += (microtime(true) - $stamp);
-                                       self::$db_duration_write += (microtime(true) - $stamp);
-                               } else {
-                                       Logger::info('Process runtime is okay', ['duration' => number_format($duration, 3), 'max' => $max_duration, 'id' => $entry["id"], 'pid' => $entry["pid"], 'command' => $command]);
-                               }
-                       }
-               }
-               DBA::close($entries);
-       }
 
        /**
         * Checks if the number of active workers exceeds the given limits
@@ -728,7 +627,7 @@ class Worker
         * @return bool Are there too much workers running?
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private static function tooMuchWorkers()
+       private static function tooMuchWorkers(): bool
        {
                $queues = DI::config()->get("system", "worker_queues", 10);
 
@@ -830,8 +729,8 @@ class Worker
                        // Are there fewer workers running as possible? Then fork a new one.
                        if (!DI::config()->get("system", "worker_dont_fork", false) && ($queues > ($active + 1)) && self::entriesExists()) {
                                Logger::info("There are fewer workers as possible, fork a new worker.", ['active' => $active, 'queues' => $queues]);
-                               if (self::isDaemonMode()) {
-                                       self::IPCSetJobState(true);
+                               if (Worker\Daemon::isMode()) {
+                                       Worker\IPC::SetJobState(true);
                                } else {
                                        self::spawnWorker();
                                }
@@ -839,8 +738,8 @@ class Worker
                }
 
                // if there are too much worker, we don't spawn a new one.
-               if (self::isDaemonMode() && ($active > $queues)) {
-                       self::IPCSetJobState(false);
+               if (Worker\Daemon::isMode() && ($active > $queues)) {
+                       Worker\IPC::SetJobState(false);
                }
 
                return $active > $queues;
@@ -852,7 +751,7 @@ class Worker
         * @return integer Number of active worker processes
         * @throws \Exception
         */
-       private static function activeWorkers()
+       private static function activeWorkers(): int
        {
                $stamp = (float)microtime(true);
                $count = DI::process()->countCommand('Worker.php');
@@ -867,7 +766,7 @@ class Worker
         * @return array List of worker process ids
         * @throws \Exception
         */
-       private static function getWorkerPIDList()
+       private static function getWorkerPIDList(): array
        {
                $ids = [];
                $stamp = (float)microtime(true);
@@ -888,7 +787,7 @@ class Worker
        /**
         * Returns waiting jobs for the current process id
         *
-        * @return array waiting workerqueue jobs
+        * @return array|bool waiting workerqueue jobs or FALSE on failture
         * @throws \Exception
         */
        private static function getWaitingJobForPID()
@@ -910,7 +809,7 @@ class Worker
         * @return array array with next jobs
         * @throws \Exception
         */
-       private static function nextProcess(int $limit)
+       private static function nextProcess(int $limit): array
        {
                $priority = self::nextPriority();
                if (empty($priority)) {
@@ -945,7 +844,7 @@ class Worker
        /**
         * Returns the priority of the next workerqueue job
         *
-        * @return string priority
+        * @return string|bool priority or FALSE on failure
         * @throws \Exception
         */
        private static function nextPriority()
@@ -1016,7 +915,7 @@ class Worker
        /**
         * Find and claim the next worker process for us
         *
-        * @return boolean Have we found something?
+        * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        private static function findWorkerProcesses()
@@ -1094,7 +993,7 @@ class Worker
         * @return array worker processes
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function workerProcess()
+       public static function workerProcess(): array
        {
                // There can already be jobs for us in the queue.
                $waiting = self::getWaitingJobForPID();
@@ -1104,7 +1003,7 @@ class Worker
 
                $stamp = (float)microtime(true);
                if (!DI::lock()->acquire(self::LOCK_PROCESS)) {
-                       return false;
+                       return [];
                }
                self::$lock_duration += (microtime(true) - $stamp);
 
@@ -1112,7 +1011,9 @@ class Worker
 
                DI::lock()->release(self::LOCK_PROCESS);
 
-               return self::getWaitingJobForPID();
+               // Prevents "Return value of Friendica\Core\Worker::workerProcess() must be of the type array, bool returned"
+               $process = self::getWaitingJobForPID();
+               return (is_array($process) ? $process : []);
        }
 
        /**
@@ -1131,26 +1032,6 @@ class Worker
                self::$db_duration_write += (microtime(true) - $stamp);
        }
 
-       /**
-        * Runs the cron processes
-        *
-        * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        */
-       private static function runCron()
-       {
-               Logger::info('Add cron entries');
-
-               // Check for spooled items
-               self::add(['priority' => PRIORITY_HIGH, 'force_priority' => true], 'SpoolPost');
-
-               // Run the cron job that calls all other jobs
-               self::add(['priority' => PRIORITY_MEDIUM, 'force_priority' => true], 'Cron');
-
-               // Cleaning dead processes
-               self::killStaleWorkers();
-       }
-
        /**
         * Fork a child process
         *
@@ -1176,11 +1057,11 @@ class Worker
                        // The parent process continues here
                        DBA::connect();
 
-                       self::IPCSetJobState(true, $pid);
+                       Worker\IPC::SetJobState(true, $pid);
                        Logger::info('Spawned new worker', ['pid' => $pid]);
 
                        $cycles = 0;
-                       while (self::IPCJobsExists($pid) && (++$cycles < 100)) {
+                       while (Worker\IPC::JobsExists($pid) && (++$cycles < 100)) {
                                usleep(10000);
                        }
 
@@ -1195,7 +1076,7 @@ class Worker
                $process = DI::process()->create(getmypid(), basename(__FILE__));
 
                $cycles = 0;
-               while (!self::IPCJobsExists($process->pid) && (++$cycles < 100)) {
+               while (!Worker\IPC::JobsExists($process->pid) && (++$cycles < 100)) {
                        usleep(10000);
                }
 
@@ -1205,7 +1086,7 @@ class Worker
 
                self::unclaimProcess($process);
 
-               self::IPCSetJobState(false, $process->pid);
+               Worker\IPC::SetJobState(false, $process->pid);
                DI::process()->delete($process);
                Logger::info('Worker ended', ['pid' => $process->pid]);
                exit();
@@ -1218,15 +1099,15 @@ class Worker
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function spawnWorker($do_cron = false)
+       public static function spawnWorker(bool $do_cron = false)
        {
-               if (self::isDaemonMode() && DI::config()->get('system', 'worker_fork')) {
+               if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) {
                        self::forkProcess($do_cron);
                } else {
                        DI::system()->run('bin/worker.php', ['no_cron' => !$do_cron]);
                }
-               if (self::isDaemonMode()) {
-                       self::IPCSetJobState(false);
+               if (Worker\Daemon::isMode()) {
+                       Worker\IPC::SetJobState(false);
                }
        }
 
@@ -1296,7 +1177,7 @@ class Worker
                $found = DBA::exists('workerqueue', ['command' => $command, 'parameter' => $parameters, 'done' => false]);
                $added = 0;
 
-               if (!in_array($priority, PRIORITIES)) {
+               if (!is_int($priority) || !in_array($priority, PRIORITIES)) {
                        Logger::warning('Invalid priority', ['priority' => $priority, 'command' => $command, 'callstack' => System::callstack(20)]);
                        $priority = PRIORITY_MEDIUM;
                }
@@ -1317,11 +1198,11 @@ class Worker
                }
 
                // Set the IPC flag to ensure an immediate process execution via daemon
-               if (self::isDaemonMode()) {
-                       self::IPCSetJobState(true);
+               if (Worker\Daemon::isMode()) {
+                       Worker\IPC::SetJobState(true);
                }
 
-               self::checkDaemonState();
+               Worker\Daemon::checkState();
 
                // Should we quit and wait for the worker to be called as a cronjob?
                if ($dont_fork) {
@@ -1342,7 +1223,7 @@ class Worker
                }
 
                // Quit on daemon mode
-               if (self::isDaemonMode()) {
+               if (Worker\Daemon::isMode()) {
                        return $added;
                }
 
@@ -1352,7 +1233,7 @@ class Worker
                return $added;
        }
 
-       public static function countWorkersByCommand(string $command)
+       public static function countWorkersByCommand(string $command): int
        {
                return DBA::count('workerqueue', ['done' => false, 'pid' => 0, 'command' => $command]);
        }
@@ -1365,7 +1246,7 @@ class Worker
         * @param integer $max_level maximum retrial level
         * @return integer the next retrial level value
         */
-       private static function getNextRetrial($queue, $max_level)
+       private static function getNextRetrial(array $queue, int $max_level): int
        {
                $created = strtotime($queue['created']);
                $retrial_time = time() - $created;
@@ -1397,8 +1278,6 @@ class Worker
                        return false;
                }
 
-               $queue = self::checkPriority($queue);
-
                $id = $queue['id'];
                $priority = $queue['priority'];
 
@@ -1434,165 +1313,13 @@ class Worker
                return true;
        }
 
-       /**
-        * 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');
-       }
-
        /**
         * Check if the system is inside the defined maintenance window
         *
+        * @param bool $check_last_execution Whether check last execution
         * @return boolean
         */
-       public static function isInMaintenanceWindow(bool $check_last_execution = false)
+       public static function isInMaintenanceWindow(bool $check_last_execution = false): bool
        {
                // Calculate the seconds of the start end end of the maintenance window
                $start = strtotime(DI::config()->get('system', 'maintenance_start')) % 86400;