<?php
/**
- * @copyright Copyright (C) 2010-2022, the Friendica project
+ * @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
if (DI::lock()->acquire(self::LOCK_WORKER, 0)) {
// Count active workers and compare them with a maximum value that depends on the load
if (self::tooMuchWorkers()) {
- Logger::notice('Active worker limit reached, quitting.');
+ Logger::info('Active worker limit reached, quitting.');
DI::lock()->release(self::LOCK_WORKER);
return;
}
{
// Count active workers and compare them with a maximum value that depends on the load
if (self::tooMuchWorkers()) {
- Logger::notice('Active worker limit reached, quitting.');
+ Logger::info('Active worker limit reached, quitting.');
return false;
}
$mypid = getmypid();
// Quit when in maintenance
- if (DI::config()->get('system', 'maintenance', false, true)) {
+ if (DI::config()->get('system', 'maintenance', false)) {
Logger::notice('Maintenance mode - quit process', ['pid' => $mypid]);
return false;
}
return false;
}
- // Check for existance and validity of the include file
+ // Check for existence and validity of the include file
$include = $argv[0];
if (method_exists(sprintf('Friendica\Worker\%s', $include), 'execute')) {
while ($load = System::getLoadAvg($processes_cooldown != 0)) {
if (($load_cooldown > 0) && ($load['average1'] > $load_cooldown)) {
if (!$sleeping) {
- Logger::notice('Load induced pre execution cooldown.', ['max' => $load_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
+ Logger::info('Load induced pre execution cooldown.', ['max' => $load_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
$sleeping = true;
}
sleep(1);
}
if (($processes_cooldown > 0) && ($load['scheduled'] > $processes_cooldown)) {
if (!$sleeping) {
- Logger::notice('Process induced pre execution cooldown.', ['max' => $processes_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
+ Logger::info('Process induced pre execution cooldown.', ['max' => $processes_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
$sleeping = true;
}
sleep(1);
}
if ($sleeping) {
- Logger::notice('Cooldown ended.', ['max-load' => $load_cooldown, 'max-processes' => $processes_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
+ Logger::info('Cooldown ended.', ['max-load' => $load_cooldown, 'max-processes' => $processes_cooldown, 'load' => $load, 'called-by' => System::callstack(1)]);
}
}
// No need to defer a worker queue entry if the arguments are invalid
Logger::notice('Wrong worker arguments', ['class' => $funcname, 'argv' => $argv, 'queue' => $queue, 'message' => $e->getMessage()]);
} catch (\Throwable $e) {
- Logger::error('Uncaught exception in worker execution', ['class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile() . ':' . $e->getLine(), 'trace' => $e->getTraceAsString()]);
+ Logger::error('Uncaught exception in worker execution', ['class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile() . ':' . $e->getLine(), 'trace' => $e->getTraceAsString(), 'previous' => $e->getPrevious()]);
Worker::defer();
}
} else {
/* With these values we can analyze how effective the worker is.
* The database and rest time should be low since this is the unproductive time.
* The execution time is the productive time.
- * By changing parameters like the maximum number of workers we can check the effectivness.
+ * By changing parameters like the maximum number of workers we can check the effectiveness.
*/
$dbtotal = round(self::$db_duration, 2);
$dbread = round(self::$db_duration - (self::$db_duration_count + self::$db_duration_write + self::$db_duration_stat), 2);
DBA::close($r);
}
+ $stamp = (float)microtime(true);
+ $used = 0;
+ $sleep = 0;
+ $data = DBA::p("SHOW PROCESSLIST");
+ while ($row = DBA::fetch($data)) {
+ if ($row['Command'] != 'Sleep') {
+ ++$used;
+ } else {
+ ++$sleep;
+ }
+ }
+ DBA::close($data);
+ self::$db_duration += (microtime(true) - $stamp);
+
// If $max is set we will use the processlist to determine the current number of connections
// The processlist only shows entries of the current user
if ($max != 0) {
- $stamp = (float)microtime(true);
- $r = DBA::p('SHOW PROCESSLIST');
- self::$db_duration += (microtime(true) - $stamp);
- $used = DBA::numRows($r);
- DBA::close($r);
-
- Logger::info('Connection usage (user values)', ['usage' => $used, 'max' => $max]);
+ Logger::info('Connection usage (user values)', ['working' => $used, 'sleeping' => $sleep, 'max' => $max]);
$level = ($used / $max) * 100;
if (!DBA::isResult($r)) {
return false;
}
- $used = intval($r['Value']);
+ $used = max($used, intval($r['Value'])) - $sleep;
if ($used == 0) {
return false;
}
- Logger::info('Connection usage (system values)', ['used' => $used, 'max' => $max]);
+ Logger::info('Connection usage (system values)', ['working' => $used, 'sleeping' => $sleep, 'max' => $max]);
$level = $used / $max * 100;
}
}
- Logger::notice('Load: ' . $load . '/' . $maxsysload . ' - processes: ' . $deferred . '/' . $active . '/' . $waiting_processes . $processlist . ' - maximum: ' . $queues . '/' . $maxqueues);
+ Logger::info('Load: ' . $load . '/' . $maxsysload . ' - processes: ' . $deferred . '/' . $active . '/' . $waiting_processes . $processlist . ' - maximum: ' . $queues . '/' . $maxqueues);
// 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() && !self::systemLimitReached()) {
/**
* Returns waiting jobs for the current process id
*
- * @return array|bool waiting workerqueue jobs or FALSE on failture
+ * @return array|bool waiting workerqueue jobs or FALSE on failure
* @throws \Exception
*/
private static function getWaitingJobForPID()
$command = array_shift($args);
$parameters = json_encode($args);
- $queue = DBA::selectFirst('workerqueue', [], ['command' => $command, 'parameter' => $parameters, 'done' => false]);
+ $queue = DBA::selectFirst('workerqueue', ['id', 'priority'], ['command' => $command, 'parameter' => $parameters, 'done' => false]);
$added = 0;
if (!is_int($priority) || !in_array($priority, self::PRIORITIES)) {
return $added;
}
- // Quit on daemon mode
- if (Worker\Daemon::isMode()) {
+ // Quit on daemon mode, except the priority is critical (like for db updates)
+ if (Worker\Daemon::isMode() && $priority !== self::PRIORITY_CRITICAL) {
return $added;
}
*/
public static function isInMaintenanceWindow(bool $check_last_execution = false): bool
{
- // Calculate the seconds of the start end end of the maintenance window
+ // Calculate the seconds of the start and end of the maintenance window
$start = strtotime(DI::config()->get('system', 'maintenance_start')) % 86400;
$end = strtotime(DI::config()->get('system', 'maintenance_end')) % 86400;