diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index 30202bbd93..68ee53a8b0 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -52,6 +52,7 @@ require dirname(__FILE__, 2) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(require(dirname(__FILE__, 2) . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); +$container = \Friendica\Core\Container::fromDice($dice); +$app = \Friendica\App::fromContainer($container); $app->processEjabberd(); diff --git a/bin/console.php b/bin/console.php index 1c502cc673..63412887d5 100755 --- a/bin/console.php +++ b/bin/console.php @@ -19,6 +19,5 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); - -$app->processConsole($_SERVER['argv'] ?? []); +$container = \Friendica\Core\Container::fromDice($dice); +\Friendica\Core\Console::create($container, $_SERVER['argv'] ?? [])->execute(); diff --git a/bin/daemon.php b/bin/daemon.php index 499bbc5d9b..18af315bc3 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: AGPL-3.0-or-later * - * @deprecated 2025.01 use bin/console.php daemon instead + * @deprecated 2025.02 use bin/console.php daemon instead */ /** @@ -28,9 +28,8 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); - $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "daemon"); -$app->processConsole($argv); +$container = \Friendica\Core\Container::fromDice($dice); +\Friendica\Core\Console::create($container, $argv)->execute(); diff --git a/bin/dev/vagrant_provision.sh b/bin/dev/vagrant_provision.sh index 46459fd869..7078b84d64 100755 --- a/bin/dev/vagrant_provision.sh +++ b/bin/dev/vagrant_provision.sh @@ -129,7 +129,7 @@ bin/console user password "$USER_NICK" "$USER_PASSW" # create cronjob - activate if you have enough memory in you dev VM # cronjob runs as www-data user echo ">>> Installing cronjob" -echo "*/10 * * * * www-data cd /vagrant; /usr/bin/php bin/worker.php" >> /etc/cron.d/friendica +echo "*/10 * * * * www-data cd /vagrant; /usr/bin/php bin/console.php worker" >> /etc/cron.d/friendica # friendica needs write access to /tmp chmod 777 /tmp diff --git a/bin/jetstream.php b/bin/jetstream.php index f1834c783b..e3df667d3f 100755 --- a/bin/jetstream.php +++ b/bin/jetstream.php @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: AGPL-3.0-or-later * - * @deprecated 2025.01 use bin/console.php jetstream instead + * @deprecated 2025.02 use bin/console.php jetstream instead */ use Dice\Dice; @@ -23,9 +23,8 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); - $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "jetstream"); -$app->processConsole($argv); +$container = \Friendica\Core\Container::fromDice($dice); +\Friendica\Core\Console::create($container, $argv)->execute(); diff --git a/bin/worker.php b/bin/worker.php index b88c30aeb5..a58d657a0f 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -7,6 +7,8 @@ * SPDX-License-Identifier: AGPL-3.0-or-later * * Starts the background processing + * + * @deprecated 2025.02 use bin/console.php worker instead */ if (php_sapi_name() !== 'cli') { @@ -16,9 +18,6 @@ if (php_sapi_name() !== 'cli') { use Dice\Dice; -// Get options -$options = getopt('sn', ['spawn', 'no_cron']); - // Ensure that worker.php is executed from the base path of the installation chdir(dirname(__DIR__)); @@ -26,6 +25,8 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); +$argv = $_SERVER['argv'] ?? []; +array_splice($argv, 1, 0, "worker"); -$app->processWorker($options ?: []); +$container = \Friendica\Core\Container::fromDice($dice); +\Friendica\Core\Console::create($container, $argv)->execute(); diff --git a/doc/Install.md b/doc/Install.md index 936d46c7a9..68bc934776 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -268,7 +268,7 @@ You might wish to delete/rename `config/local.config.php` to another name and dr Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing. Example: - cd /base/directory; /path/to/php bin/worker.php + cd /base/directory; /path/to/php bin/console.php worker Change "/base/directory", and "/path/to/php" as appropriate for your situation. @@ -277,7 +277,7 @@ Change "/base/directory", and "/path/to/php" as appropriate for your situation. If you are using a Linux server, run "crontab -e" and add a line like the one shown, substituting for your unique paths and settings: - */10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/worker.php + */10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/console.php worker You can generally find the location of PHP by executing "which php". If you run into trouble with this section please contact your hosting provider for assistance. @@ -290,11 +290,11 @@ Once you have installed Friendica and created an admin account as part of the pr #### worker alternative: daemon Otherwise, you’ll need to use the command line on your remote server and start the Friendica daemon (background task) using the following command: - cd /path/to/friendica; php bin/daemon.php start + cd /path/to/friendica; php bin/console.php daemon start Once started, you can check the daemon status using the following command: - cd /path/to/friendica; php bin/daemon.php status + cd /path/to/friendica; php bin/console.php daemon status After a server restart or any other failure, the daemon needs to be restarted. This could be achieved by a cronjob. @@ -426,7 +426,7 @@ provided by one of our members. > > */10 * * * * cd /var/www/friendica/friendica/ && sudo -u www-data /usr/bin/php \ > -d suhosin.executor.func.blacklist=none \ -> -d suhosin.executor.eval.blacklist=none -f bin/worker.php +> -d suhosin.executor.eval.blacklist=none -f bin/console.php > > This worked well for simple test cases, but the friendica-cron still failed > with a fatal error: @@ -435,7 +435,7 @@ provided by one of our members. > (attacker 'REMOTE_ADDR not set', file '/var/www/friendica/friendica/boot.php', > line 1341) > -> After a while I noticed, that `bin/worker.php` calls further PHP script via `proc_open`. +> After a while I noticed, that `bin/console.php worker` calls further PHP script via `proc_open`. > These scripts themselves also use `proc_open` and fail, because they are NOT > called with `-d suhosin.executor.func.blacklist=none`. > diff --git a/doc/Installing-Connectors.md b/doc/Installing-Connectors.md index 48c3c9fb1e..bd564eb466 100644 --- a/doc/Installing-Connectors.md +++ b/doc/Installing-Connectors.md @@ -28,7 +28,7 @@ Jetstream is a service that connects to the Bluesky firehose. With Jetstream, messages arrive in real time rather than having to be polled. It also enables real-time processing of blocks or tracking activities performed by the user via the Bluesky website or application. -To enable Jetstream processing, run `bin/jetstream.php' from the command line. +To enable Jetstream processing, run `bin/console.php jetstream' from the command line. You will need to define the process id file in local.config.php in the 'jetstream' section using the key 'pidfile'. -To keep track of the messages processed and the drift (the time difference between the date of the message and the date the system processed that message), some fields are added to the statistics endpoint. \ No newline at end of file +To keep track of the messages processed and the drift (the time difference between the date of the message and the date the system processed that message), some fields are added to the statistics endpoint. diff --git a/doc/Migrate.md b/doc/Migrate.md index e116d029f6..ca0e0d0d95 100644 --- a/doc/Migrate.md +++ b/doc/Migrate.md @@ -55,9 +55,9 @@ You should see an output like this: Finally, you may also want to optimise your database with the following command: ``mysqloptimize -p friendica-db`` -### Going offline +### Going offline Stop background tasks and put your server in maintenance mode. -1. If you had set up a worker cron job like this ``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/worker.php`` run ``crontab -e`` and comment out this line. Alternatively if you deploy a worker daemon, disable this instead. +1. If you had set up a worker cron job like this ``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/console.php worker`` run ``crontab -e`` and comment out this line. Alternatively if you deploy a worker daemon, disable this instead. 2. Put your server into maintenance mode: ``bin/console maintenance 1 "We are currently upgrading our system and will be back soon."`` ## Dumping DB @@ -73,12 +73,12 @@ Import your database on your new server: ``mysql -p friendica_db < your-friendic ### Configuration file Copy your old server's configuration file to ``config/local.config.php``. -Ensure the newly created database credentials are identical to the setting in the configuration file; otherwise update them accordingly. +Ensure the newly created database credentials are identical to the setting in the configuration file; otherwise update them accordingly. ### Cron job for worker Set up the required daily cron job. Run ``crontab -e`` and add the following line according to your system specification -``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/worker.php`` +``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/console.php worker`` ### DNS settings Adjust your DNS records by pointing them to your new server. diff --git a/doc/de/Install.md b/doc/de/Install.md index 147a9aebc7..ae910e6fab 100644 --- a/doc/de/Install.md +++ b/doc/de/Install.md @@ -210,13 +210,13 @@ Gehe in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus: Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen. Beispiel: - cd /base/directory; /path/to/php bin/worker.php + cd /base/directory; /path/to/php bin/console.php worker Ändere "/base/directory" und "/path/to/php" auf deine Systemvorgaben. Wenn du einen Linux-Server nutzt, benutze den Befehl "crontab -e" und ergänze eine Zeile wie die Folgende; angepasst an dein System -`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/worker.php` +`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/console.php worker` Du kannst den PHP-Pfad finden, indem du den Befehl „which php“ ausführst. Wenn du Schwierigkeiten mit diesem Schritt hast, kannst du deinen Hosting-Anbieter kontaktieren. diff --git a/doc/de/Installing-Connectors.md b/doc/de/Installing-Connectors.md index 1ca152ace9..7d378e2374 100644 --- a/doc/de/Installing-Connectors.md +++ b/doc/de/Installing-Connectors.md @@ -27,7 +27,7 @@ Jetstream ist ein Dienst, der sich mit dem Bluesky-Firehose verbindet. Mit Jetstream kommen die Nachrichten in Echtzeit an und müssen nicht erst abgefragt werden. Es ermöglicht auch die Echtzeitverarbeitung von Blöcken oder Tracking-Aktivitäten, die über die Bluesky-Website oder -Anwendung durchgeführt werden. -Um die Jetstream-Verarbeitung zu aktivieren, führe `bin/jetstream.php' über die Befehlszeile aus. +Um die Jetstream-Verarbeitung zu aktivieren, führe `bin/console.php daemon' über die Befehlszeile aus. Du musst vorher die Prozess-ID-Datei in local.config.php im Abschnitt „jetstream“ mit dem Schlüssel „pidfile“ definieren. Um die verarbeiteten Nachrichten und die Drift (die Zeitdifferenz zwischen dem Datum der Nachricht und dem Datum, an dem das System diese Nachricht verarbeitet hat) zu verfolgen, wurden dem Statistik-Endpunkt einige Felder hinzugefügt. diff --git a/index.php b/index.php index 5cdb309363..6654dcb515 100644 --- a/index.php +++ b/index.php @@ -19,6 +19,7 @@ $request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals(); $dice = (new Dice())->addRules(require(__DIR__ . '/static/dependencies.config.php')); -$app = \Friendica\App::fromDice($dice); +$container = \Friendica\Core\Container::fromDice($dice); +$app = \Friendica\App::fromContainer($container); $app->processRequest($request, $start_time); diff --git a/mods/sample-systemd.service b/mods/sample-systemd.service index aae2e5825c..ac37359989 100644 --- a/mods/sample-systemd.service +++ b/mods/sample-systemd.service @@ -6,4 +6,4 @@ Description=Friendica Worker User=http #Adapt the path in the following line to your system, use 'which php' to find php path, #provide the absolute path for worker.php -ExecStart=/usr/bin/php /www/path/bin/worker.php & +ExecStart=/usr/bin/php /www/path/bin/console.php worker & diff --git a/src/App.php b/src/App.php index 923400a21c..487707f9fd 100644 --- a/src/App.php +++ b/src/App.php @@ -18,9 +18,9 @@ use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanHandleRequests; use Friendica\Content\Nav; use Friendica\Core\Config\Factory\Config; +use Friendica\Core\Container; use Friendica\Core\Renderer; use Friendica\Core\Session\Capability\IHandleUserSessions; -use Friendica\Core\Worker\Repository\Process as ProcessRepository; use Friendica\Database\Definition\DbaDefinition; use Friendica\Database\Definition\ViewDefinition; use Friendica\Module\Maintenance; @@ -31,7 +31,6 @@ use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; use Friendica\Core\System; use Friendica\Core\Update; -use Friendica\Core\Worker; use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Network\HTTPException; use Friendica\Protocol\ATProtocol\DID; @@ -61,13 +60,13 @@ class App const CODENAME = 'Interrupted Fern'; const VERSION = '2025.02-dev'; - public static function fromDice(Dice $dice): self + public static function fromContainer(Container $container): self { - return new self($dice); + return new self($container); } /** - * @var Dice + * @var Container */ private $container; @@ -122,26 +121,20 @@ class App */ private $appHelper; - private function __construct(Dice $container) + private function __construct(Container $container) { $this->container = $container; } public function processRequest(ServerRequestInterface $request, float $start_time): void { - $this->setupContainerForAddons(); - - $this->setupContainerForLogger(LogChannel::DEFAULT); - - $this->container = $this->container->addRule(Mode::class, [ + $this->container->addRule(Mode::class, [ 'call' => [ ['determineRunMode', [false, $request->getServerParams()], Dice::CHAIN_CALL], ], ]); - $this->setupLegacyServiceLocator(); - - $this->registerErrorHandler(); + $this->container->setup(LogChannel::APP, false); $this->requestId = $this->container->create(Request::class)->getRequestId(); $this->auth = $this->container->create(Authentication::class); @@ -177,13 +170,7 @@ class App public function processEjabberd(): void { - $this->setupContainerForAddons(); - - $this->setupContainerForLogger(LogChannel::AUTH_JABBERED); - - $this->setupLegacyServiceLocator(); - - $this->registerErrorHandler(); + $this->container->setup(LogChannel::AUTH_JABBERED, false); /** @var BasePath */ $basePath = $this->container->create(BasePath::class); @@ -200,95 +187,6 @@ class App } } - public function processConsole(array $argv): void - { - $this->setupContainerForAddons(); - - $this->setupContainerForLogger(LogChannel::CONSOLE); - - $this->setupLegacyServiceLocator(); - - $this->registerErrorHandler(); - - $this->registerTemplateEngine(); - - (new \Friendica\Core\Console($this->container, $argv))->execute(); - } - - public function processWorker(array $options): void - { - $this->setupContainerForAddons(); - - $this->setupContainerForLogger(LogChannel::WORKER); - - $this->setupLegacyServiceLocator(); - - $this->registerErrorHandler(); - - $this->registerTemplateEngine(); - - /** @var Mode */ - $mode = $this->container->create(Mode::class); - - $mode->setExecutor(Mode::WORKER); - - /** @var BasePath */ - $basePath = $this->container->create(BasePath::class); - - // Check the database structure and possibly fixes it - Update::check($basePath->getPath(), true); - - // Quit when in maintenance - if (!$mode->has(Mode::MAINTENANCEDISABLED)) { - return; - } - - $spawn = array_key_exists('s', $options) || array_key_exists('spawn', $options); - - if ($spawn) { - Worker::spawnWorker(); - exit(); - } - - $run_cron = !array_key_exists('n', $options) && !array_key_exists('no_cron', $options); - - /** @var ProcessRepository */ - $processRepository = $this->container->create(ProcessRepository::class); - - $process = $processRepository->create(getmypid(), 'worker.php'); - - Worker::processQueue($run_cron, $process); - - Worker::unclaimProcess($process); - - $processRepository->delete($process); - } - - private function setupContainerForAddons(): void - { - /** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ - $addonLoader = $this->container->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); - - $this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies')); - } - - private function setupContainerForLogger(string $logChannel): void - { - $this->container = $this->container->addRule(LoggerInterface::class, [ - 'constructParams' => [$logChannel], - ]); - } - - private function setupLegacyServiceLocator(): void - { - DI::init($this->container); - } - - private function registerErrorHandler(): void - { - \Friendica\Core\Logger\Handler\ErrorHandler::register($this->container->create(LoggerInterface::class)); - } - private function registerTemplateEngine(): void { Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine'); diff --git a/src/Console/AbstractConsole.php b/src/Console/AbstractConsole.php new file mode 100644 index 0000000000..f9c413b915 --- /dev/null +++ b/src/Console/AbstractConsole.php @@ -0,0 +1,39 @@ +executable, -strlen(CoreConsole::getDefaultExecutable())) === CoreConsole::getDefaultExecutable()) { + $this->out(sprintf("'%s' is deprecated and will removed. Please use 'bin/console.php %s' instead", $this->executable, $command)); + } + } +} diff --git a/src/Console/Daemon.php b/src/Console/Daemon.php index eac7b935a8..c8165a1d9b 100644 --- a/src/Console/Daemon.php +++ b/src/Console/Daemon.php @@ -9,10 +9,11 @@ declare(strict_types=1); namespace Friendica\Console; +use Asika\SimpleConsole\CommandArgsException; use Friendica\App\Mode; use Friendica\Core\Config\Capability\IManageConfigValues; -use Asika\SimpleConsole\Console; use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Core\System; use Friendica\Core\Update; use Friendica\Core\Worker; @@ -26,8 +27,10 @@ use RuntimeException; /** * Console command for interacting with the daemon */ -final class Daemon extends Console +final class Daemon extends AbstractConsole { + public const LOG_CHANNEL = LogChannel::DAEMON; + private Mode $mode; private IManageConfigValues $config; private IManageKeyValuePairs $keyValue; @@ -90,9 +93,7 @@ HELP; protected function doExecute() { - if ($this->executable !== 'bin/console.php') { - $this->out(sprintf("'%s' is deprecated and will removed. Please use 'bin/console.php daemon' instead", $this->executable)); - } + $this->checkDeprecated('daemon'); if ($this->mode->isInstall()) { throw new RuntimeException("Friendica isn't properly installed yet"); @@ -120,7 +121,7 @@ HELP; $foreground = $this->getOption(['f', 'foreground']) ?? false; if (empty($daemonMode)) { - throw new RuntimeException("Please use either 'start', 'stop' or 'status'"); + throw new CommandArgsException("Please use either 'start', 'stop' or 'status'"); } $this->daemon->init($pidfile); diff --git a/src/Console/JetstreamDaemon.php b/src/Console/JetstreamDaemon.php index 133bf9c073..d34e5780c2 100644 --- a/src/Console/JetstreamDaemon.php +++ b/src/Console/JetstreamDaemon.php @@ -12,9 +12,9 @@ namespace Friendica\Console; use Friendica\App\Mode; use Friendica\Core\Addon; use Friendica\Core\Config\Capability\IManageConfigValues; -use Asika\SimpleConsole\Console; use Friendica\Core\Hook; use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Protocol\ATProtocol\Jetstream; use Friendica\System\Daemon as SysDaemon; use RuntimeException; @@ -22,8 +22,10 @@ use RuntimeException; /** * Console command for interacting with the daemon */ -final class JetstreamDaemon extends Console +final class JetstreamDaemon extends AbstractConsole { + public const LOG_CHANNEL = LogChannel::DAEMON; + private Mode $mode; private IManageConfigValues $config; private IManageKeyValuePairs $keyValue; @@ -77,9 +79,7 @@ HELP; protected function doExecute() { - if ($this->executable !== 'bin/console.php') { - $this->out(sprintf("'%s' is deprecated and will removed. Please use 'bin/console.php jetstream' instead", $this->executable)); - } + $this->checkDeprecated('jetstream'); if ($this->mode->isInstall()) { throw new RuntimeException("Friendica isn't properly installed yet"); diff --git a/src/Console/Worker.php b/src/Console/Worker.php new file mode 100644 index 0000000000..1c7eeae002 --- /dev/null +++ b/src/Console/Worker.php @@ -0,0 +1,100 @@ +mode = $mode; + $this->basePath = $basePath; + $this->processRepo = $processRepo; + } + + protected function getHelp(): string + { + return <<checkDeprecated('worker'); + + $this->mode->setExecutor(Mode::WORKER); + + // Check the database structure and possibly fixes it + Update::check($this->basePath->getPath(), true); + + // Quit when in maintenance + if (!$this->mode->has(Mode::MAINTENANCEDISABLED)) { + return; + } + + $spawn = $this->getOption(['s', 'spawn'], false); + + if ($spawn) { + CoreWorker::spawnWorker(); + exit(); + } + + $run_cron = !$this->getOption(['n', 'no_cron'], false); + + $process = $this->processRepo->create(getmypid(), 'worker.php'); + + CoreWorker::processQueue($run_cron, $process); + CoreWorker::unclaimProcess($process); + + $this->processRepo->delete($process); + } +} diff --git a/src/Core/Console.php b/src/Core/Console.php index 6865a4d25a..d138a9dfa9 100644 --- a/src/Core/Console.php +++ b/src/Core/Console.php @@ -7,23 +7,34 @@ namespace Friendica\Core; -use Dice\Dice; use Friendica; use Friendica\App; +use Friendica\Core\Logger\Capability\LogChannel; /** * Description of Console */ class Console extends \Asika\SimpleConsole\Console { - // Disables the default help handling - protected $helpOptions = []; - protected $customHelpOptions = ['h', 'help', '?']; + /** @var string The default executable for a console call */ + private const CONSOLE_EXECUTABLE = 'bin/console.php'; /** - * @var Dice The DI library + * @return string The default executable for a console call */ - protected $dice; + public static function getDefaultExecutable(): string + { + return self::CONSOLE_EXECUTABLE; + } + + // Disables the default help handling + protected $helpOptions = []; + protected array $customHelpOptions = ['h', 'help', '?']; + + /** + * @var Container The Container + */ + protected Container $container; protected function getHelp() { @@ -39,6 +50,7 @@ Commands: createdoxygen Generate Doxygen headers daemon Interact with the Friendica daemon jetstream Interact with the Jetstream daemon + worker Start worker process dbstructure Do database updates docbloxerrorchecker Check the file tree for DocBlox errors extract Generate translation string file for the Friendica project (deprecated) @@ -68,7 +80,7 @@ HELP; return $help; } - protected $subConsoles = [ + protected array $subConsoles = [ 'addon' => Friendica\Console\Addon::class, 'archivecontact' => Friendica\Console\ArchiveContact::class, 'autoinstall' => Friendica\Console\AutomaticInstallation::class, @@ -79,6 +91,7 @@ HELP; 'createdoxygen' => Friendica\Console\CreateDoxygen::class, 'daemon' => Friendica\Console\Daemon::class, 'jetstream' => Friendica\Console\JetstreamDaemon::class, + 'worker' => Friendica\Console\Worker::class, 'docbloxerrorchecker' => Friendica\Console\DocBloxErrorChecker::class, 'dbstructure' => Friendica\Console\DatabaseStructure::class, 'extract' => Friendica\Console\Extract::class, @@ -104,14 +117,18 @@ HELP; /** * CliInput Friendica constructor. * - * @param Dice $dice The DI library - * @param array $argv + * @param Container $container The Friendica container */ - public function __construct(Dice $dice, array $argv = null) + public function __construct(Container $container, array $argv = null) { parent::__construct($argv); - $this->dice = $dice; + $this->container = $container; + } + + public static function create(Container $container, array $argv = null): Console + { + return new self($container, $argv); } protected function doExecute(): int @@ -170,8 +187,14 @@ HELP; $className = $this->subConsoles[$command]; + if (is_subclass_of($className, Friendica\Console\AbstractConsole::class)) { + $this->container->setup($className::LOG_CHANNEL); + } else { + $this->container->setup(LogChannel::CONSOLE); + } + /** @var Console $subconsole */ - $subconsole = $this->dice->create($className, [$subargs]); + $subconsole = $this->container->create($className, [$subargs]); foreach ($this->options as $name => $value) { $subconsole->setOption($name, $value); @@ -179,5 +202,4 @@ HELP; return $subconsole; } - } diff --git a/src/Core/Container.php b/src/Core/Container.php new file mode 100644 index 0000000000..12a9b625a7 --- /dev/null +++ b/src/Core/Container.php @@ -0,0 +1,118 @@ +container = $container; + } + + /** + * Creates an instance with Dice + * + * @param Dice $container + * + * @return self + */ + public static function fromDice(Dice $container): self + { + return new self($container); + } + + /** + * Initialize the container with the given parameters + * + * @param string $logChannel The Log Channel of this call + * @param bool $withTemplateEngine true, if the template engine should be set too + * + * @return void + */ + public function setup(string $logChannel = LogChannel::DEFAULT, bool $withTemplateEngine = true) + { + $this->setupContainerForAddons(); + $this->setupContainerForLogger($logChannel); + $this->setupLegacyServiceLocator(); + $this->registerErrorHandler(); + + if ($withTemplateEngine) { + $this->registerTemplateEngine(); + } + } + + /** + * Returns a fully constructed object based on $name using $args and $share as constructor arguments if supplied + * @param string $name name The name of the class to instantiate + * @param array $args An array with any additional arguments to be passed into the constructor upon instantiation + * @param array $share a list of defined in shareInstances for objects higher up the object graph, should only be used internally + * @return object A fully constructed object based on the specified input arguments + * + * @see Dice::create() + */ + public function create(string $name, array $args = [], array $share = []): object + { + return $this->container->create($name, $args, $share); + } + + /** + * Add a rule $rule to the class $name + * @param string $name The name of the class to add the rule for + * @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules. + * + * @see Dice::addRule() + */ + public function addRule(string $name, array $rule): void + { + $this->container = $this->container->addRule($name, $rule); + } + + private function setupContainerForAddons(): void + { + /** @var ICanLoadAddons $addonLoader */ + $addonLoader = $this->container->create(ICanLoadAddons::class); + + $this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies')); + } + + private function setupContainerForLogger(string $logChannel): void + { + $this->container = $this->container->addRule(LoggerInterface::class, [ + 'constructParams' => [$logChannel], + ]); + } + + private function setupLegacyServiceLocator(): void + { + DI::init($this->container); + } + + private function registerErrorHandler(): void + { + ErrorHandler::register($this->container->create(LoggerInterface::class)); + } + + private function registerTemplateEngine(): void + { + Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine'); + } +} diff --git a/src/Core/System.php b/src/Core/System.php index 95a411f3d1..32fdcf3b83 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -164,9 +164,10 @@ class System * Executes a child process with 'proc_open' * * @param string $command The command to execute - * @param array $args Arguments to pass to the command ( [ 'key' => value, 'key2' => value2, ... ] + * @param array $args Arguments to pass to the command ( ['arg1', 'arg2', ... ] ) + * @param array $options Options to pass to the command ( [ 'key' => value, 'key2' => value2, ... ] */ - public function run(string $command, array $args) + public function run(string $command, array $args = [], array $options = []) { if (!function_exists('proc_open')) { $this->logger->warning('"proc_open" not available - quitting'); @@ -175,7 +176,11 @@ class System $cmdline = $this->config->get('config', 'php_path', 'php') . ' ' . escapeshellarg($command); - foreach ($args as $key => $value) { + foreach ($args as $argumment) { + $cmdline .= ' ' . $argumment; + } + + foreach ($options as $key => $value) { if (!is_null($value) && is_bool($value) && !$value) { continue; } @@ -225,7 +230,7 @@ class System $trace = array_slice($trace, 2 + $offset); $callstack = []; - $previous = ['class' => '', 'function' => '', 'database' => false]; + $previous = ['class' => '', 'function' => '', 'database' => false]; // The ignore list contains all functions that are only wrapper functions $ignore = ['call_user_func_array']; @@ -245,15 +250,15 @@ class System // Don't show multiple calls from the Database classes to show the essential parts of the callstack $func['database'] = in_array($func['class'], ['Friendica\Database\DBA', 'Friendica\Database\Database']); if ($full || !$previous['database'] || !$func['database']) { - $classparts = explode("\\", $func['class']); + $classparts = explode("\\", $func['class']); $callstack[] = array_pop($classparts).'::'.$func['function'] . (isset($func['line']) ? ' (' . $func['line'] . ')' : ''); - $previous = $func; + $previous = $func; } } elseif (!in_array($func['function'], $ignore)) { $func['database'] = ($func['function'] == 'q'); - $callstack[] = $func['function'] . (isset($func['line']) ? ' (' . $func['line'] . ')' : ''); - $func['class'] = ''; - $previous = $func; + $callstack[] = $func['function'] . (isset($func['line']) ? ' (' . $func['line'] . ')' : ''); + $func['class'] = ''; + $previous = $func; } } @@ -272,10 +277,13 @@ class System */ public static function echoResponse(ResponseInterface $response) { - header(sprintf("HTTP/%s %s %s", + header( + sprintf( + "HTTP/%s %s %s", $response->getProtocolVersion(), $response->getStatusCode(), - $response->getReasonPhrase()) + $response->getReasonPhrase() + ) ); foreach ($response->getHeaders() as $key => $header) { @@ -696,7 +704,7 @@ class System if (DI::config()->get('system', 'tosdisplay')) { $rulelist = DI::config()->get('system', 'tosrules') ?: DI::config()->get('system', 'tostext'); - $msg = BBCode::toPlaintext($rulelist, false); + $msg = BBCode::toPlaintext($rulelist, false); foreach (explode("\n", trim($msg)) as $line) { $line = trim($line); if ($line) { diff --git a/src/Core/Worker.php b/src/Core/Worker.php index c81b0be967..568fa2873f 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -45,11 +45,11 @@ class Worker const LAST_CHECK = 'worker::check'; private static $up_start; - private static $db_duration = 0; + private static $db_duration = 0; private static $db_duration_count = 0; private static $db_duration_write = 0; - private static $db_duration_stat = 0; - private static $lock_duration = 0; + private static $db_duration_stat = 0; + private static $lock_duration = 0; private static $last_update; private static $state; /** @var Process */ @@ -93,7 +93,7 @@ class Worker Worker\Cron::run(); } - $last_check = $starttime = time(); + $last_check = $starttime = time(); self::$state = self::STATE_STARTUP; // We fetch the next queue entry that is about to be executed @@ -116,7 +116,7 @@ class Worker self::findWorkerProcesses(); DI::lock()->release(self::LOCK_PROCESS); self::$state = self::STATE_REFETCH; - $refetched = true; + $refetched = true; } else { self::$state = self::STATE_SHORT_LOOP; } @@ -127,7 +127,7 @@ class Worker self::$state = self::STATE_LONG_LOOP; if (DI::lock()->acquire(self::LOCK_WORKER, 0)) { - // Count active workers and compare them with a maximum value that depends on the load + // Count active workers and compare them with a maximum value that depends on the load if (self::tooMuchWorkers()) { Logger::info('Active worker limit reached, quitting.'); DI::lock()->release(self::LOCK_WORKER); @@ -209,7 +209,7 @@ class Worker */ public static function entriesExists(): bool { - $stamp = (float)microtime(true); + $stamp = (float)microtime(true); $exists = DBA::exists('workerqueue', ["NOT `done` AND `pid` = 0 AND `next_try` < ?", DateTimeFormat::utcNow()]); self::$db_duration += (microtime(true) - $stamp); return $exists; @@ -253,8 +253,8 @@ class Worker */ private static function highestPriority(): int { - $stamp = (float)microtime(true); - $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()]; + $stamp = (float)microtime(true); + $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()]; $workerqueue = DBA::selectFirst('workerqueue', ['priority'], $condition, ['order' => ['priority']]); self::$db_duration += (microtime(true) - $stamp); if (DBA::isResult($workerqueue)) { @@ -359,7 +359,7 @@ class Worker self::$last_update = strtotime($queue['executed']); } - $age = (time() - self::$last_update) / 60; + $age = (time() - self::$last_update) / 60; self::$last_update = time(); if ($age > 1) { @@ -373,7 +373,7 @@ class Worker self::execFunction($queue, $include, $argv, true); - $stamp = (float)microtime(true); + $stamp = (float)microtime(true); $condition = ["`id` = ? AND `next_try` < ?", $queue['id'], DateTimeFormat::utcNow()]; if (DBA::update('workerqueue', ['done' => true], $condition)) { DI::keyValue()->set('last_worker_execution', DateTimeFormat::utcNow()); @@ -403,7 +403,7 @@ class Worker self::$last_update = strtotime($queue['executed']); } - $age = (time() - self::$last_update) / 60; + $age = (time() - self::$last_update) / 60; self::$last_update = time(); if ($age > 1) { @@ -595,21 +595,21 @@ class Worker self::coolDown(); - self::$up_start = microtime(true); - self::$db_duration = 0; + self::$up_start = microtime(true); + self::$db_duration = 0; self::$db_duration_count = 0; - self::$db_duration_stat = 0; + self::$db_duration_stat = 0; self::$db_duration_write = 0; - self::$lock_duration = 0; + self::$lock_duration = 0; if ($duration > 3600) { - Logger::info('Longer than 1 hour.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]); + Logger::info('Longer than 1 hour.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]); } elseif ($duration > 600) { - Logger::info('Longer than 10 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]); + Logger::info('Longer than 10 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]); } elseif ($duration > 300) { - Logger::info('Longer than 5 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]); + Logger::info('Longer than 5 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]); } elseif ($duration > 120) { - Logger::info('Longer than 2 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]); + Logger::info('Longer than 2 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]); } Logger::info('Process done.', ['function' => $funcname, 'priority' => $queue['priority'], 'retrial' => $queue['retrial'], 'id' => $queue['id'], 'duration' => round($duration, 3)]); @@ -639,7 +639,7 @@ class Worker } // Or it can be granted. This overrides the system variable $stamp = (float)microtime(true); - $r = DBA::p('SHOW GRANTS'); + $r = DBA::p('SHOW GRANTS'); self::$db_duration += (microtime(true) - $stamp); while ($grants = DBA::fetch($r)) { $grant = array_pop($grants); @@ -655,7 +655,7 @@ class Worker $stamp = (float)microtime(true); $used = 0; $sleep = 0; - $data = DBA::p("SHOW PROCESSLIST"); + $data = DBA::p("SHOW PROCESSLIST"); while ($row = DBA::fetch($data)) { if ($row['Command'] != 'Sleep') { ++$used; @@ -734,13 +734,13 @@ class Worker * With exponent 1, you could have 20 max queues at idle and 13 at 37% of $maxsysload. */ $exponent = intval(DI::config()->get('system', 'worker_load_exponent', 3)); - $slope = pow(max(0, $maxsysload - $load) / $maxsysload, $exponent); - $queues = intval(ceil($slope * $maxqueues)); + $slope = pow(max(0, $maxsysload - $load) / $maxsysload, $exponent); + $queues = intval(ceil($slope * $maxqueues)); $processlist = ''; if (DI::config()->get('system', 'worker_jpm')) { - $intervals = explode(',', DI::config()->get('system', 'worker_jpm_range')); + $intervals = explode(',', DI::config()->get('system', 'worker_jpm_range')); $jobs_per_minute = []; foreach ($intervals as $interval) { if ($interval == 0) { @@ -750,7 +750,7 @@ class Worker } $stamp = (float)microtime(true); - $jobs = DBA::count('workerqueue', ["`done` AND `executed` > ?", DateTimeFormat::utc('now - ' . $interval . ' minute')]); + $jobs = DBA::count('workerqueue', ["`done` AND `executed` > ?", DateTimeFormat::utc('now - ' . $interval . ' minute')]); self::$db_duration += (microtime(true) - $stamp); self::$db_duration_stat += (microtime(true) - $stamp); $jobs_per_minute[$interval] = number_format($jobs / $interval, 0); @@ -769,11 +769,11 @@ class Worker $waiting_processes = 0; // Now adding all processes with workerqueue entries $stamp = (float)microtime(true); - $jobs = DBA::p("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` WHERE NOT `done` GROUP BY `priority`"); + $jobs = DBA::p("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` WHERE NOT `done` GROUP BY `priority`"); self::$db_duration += (microtime(true) - $stamp); self::$db_duration_stat += (microtime(true) - $stamp); while ($entry = DBA::fetch($jobs)) { - $stamp = (float)microtime(true); + $stamp = (float)microtime(true); $running = DBA::count('workerqueue-view', ['priority' => $entry['priority']]); self::$db_duration += (microtime(true) - $stamp); self::$db_duration_stat += (microtime(true) - $stamp); @@ -783,9 +783,9 @@ class Worker } DBA::close($jobs); } else { - $waiting_processes = self::totalEntries(); - $stamp = (float)microtime(true); - $jobs = DBA::p("SELECT COUNT(*) AS `running`, `priority` FROM `workerqueue-view` GROUP BY `priority` ORDER BY `priority`"); + $waiting_processes = self::totalEntries(); + $stamp = (float)microtime(true); + $jobs = DBA::p("SELECT COUNT(*) AS `running`, `priority` FROM `workerqueue-view` GROUP BY `priority` ORDER BY `priority`"); self::$db_duration += (microtime(true) - $stamp); self::$db_duration_stat += (microtime(true) - $stamp); @@ -871,7 +871,7 @@ class Worker */ private static function getWorkerPIDList(): array { - $ids = []; + $ids = []; $stamp = (float)microtime(true); $queues = DBA::p("SELECT `process`.`pid`, COUNT(`workerqueue`.`pid`) AS `entries` FROM `process` @@ -896,7 +896,7 @@ class Worker private static function getWaitingJobForPID() { $stamp = (float)microtime(true); - $r = DBA::select('workerqueue', [], ['pid' => getmypid(), 'done' => false]); + $r = DBA::select('workerqueue', [], ['pid' => getmypid(), 'done' => false]); self::$db_duration += (microtime(true) - $stamp); if (DBA::isResult($r)) { return DBA::toArray($r); @@ -920,10 +920,10 @@ class Worker return []; } - $ids = []; - $stamp = (float)microtime(true); + $ids = []; + $stamp = (float)microtime(true); $condition = ["`priority` = ? AND `pid` = 0 AND NOT `done` AND `next_try` < ?", $priority, DateTimeFormat::utcNow()]; - $tasks = DBA::select('workerqueue', ['id', 'command', 'parameter'], $condition, ['limit' => $limit, 'order' => ['retrial', 'created']]); + $tasks = DBA::select('workerqueue', ['id', 'command', 'parameter'], $condition, ['limit' => $limit, 'order' => ['retrial', 'created']]); self::$db_duration += (microtime(true) - $stamp); while ($task = DBA::fetch($tasks)) { $ids[] = $task['id']; @@ -952,7 +952,7 @@ class Worker */ private static function nextPriority() { - $waiting = []; + $waiting = []; $priorities = [self::PRIORITY_CRITICAL, self::PRIORITY_HIGH, self::PRIORITY_MEDIUM, self::PRIORITY_LOW, self::PRIORITY_NEGLIGIBLE]; foreach ($priorities as $priority) { $stamp = (float)microtime(true); @@ -966,10 +966,10 @@ class Worker return self::PRIORITY_CRITICAL; } - $running = []; + $running = []; $running_total = 0; - $stamp = (float)microtime(true); - $processes = DBA::p("SELECT COUNT(DISTINCT(`pid`)) AS `running`, `priority` FROM `workerqueue-view` GROUP BY `priority`"); + $stamp = (float)microtime(true); + $processes = DBA::p("SELECT COUNT(DISTINCT(`pid`)) AS `running`, `priority` FROM `workerqueue-view` GROUP BY `priority`"); self::$db_duration += (microtime(true) - $stamp); while ($process = DBA::fetch($processes)) { $running[$process['priority']] = $process['running']; @@ -984,9 +984,9 @@ class Worker } } - $active = max(self::activeWorkers(), $running_total); + $active = max(self::activeWorkers(), $running_total); $priorities = max(count($waiting), count($running)); - $exponent = 2; + $exponent = 2; $total = 0; for ($i = 1; $i <= $priorities; ++$i) { @@ -1037,7 +1037,7 @@ class Worker } $limit = $fetch_limit * count($pids); } else { - $pids = [getmypid()]; + $pids = [getmypid()]; $limit = $fetch_limit; } @@ -1046,9 +1046,9 @@ class Worker // If there is not enough results we check without priority limit if ($limit > 0) { - $stamp = (float)microtime(true); + $stamp = (float)microtime(true); $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()]; - $tasks = DBA::select('workerqueue', ['id', 'command', 'parameter'], $condition, ['limit' => $limit, 'order' => ['priority', 'retrial', 'created']]); + $tasks = DBA::select('workerqueue', ['id', 'command', 'parameter'], $condition, ['limit' => $limit, 'order' => ['priority', 'retrial', 'created']]); self::$db_duration += (microtime(true) - $stamp); while ($task = DBA::fetch($tasks)) { @@ -1083,8 +1083,11 @@ class Worker $stamp = (float)microtime(true); foreach ($worker as $worker_pid => $worker_ids) { Logger::info('Set queue entry', ['pid' => $worker_pid, 'ids' => $worker_ids]); - DBA::update('workerqueue', ['executed' => DateTimeFormat::utcNow(), 'pid' => $worker_pid], - ['id' => $worker_ids, 'done' => false, 'pid' => 0]); + DBA::update( + 'workerqueue', + ['executed' => DateTimeFormat::utcNow(), 'pid' => $worker_pid], + ['id' => $worker_ids, 'done' => false, 'pid' => 0] + ); } self::$db_duration += (microtime(true) - $stamp); self::$db_duration_write += (microtime(true) - $stamp); @@ -1207,7 +1210,7 @@ class Worker 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]); + DI::system()->run('bin/console.php', ['worker'], ['no_cron' => !$do_cron]); } if (Worker\Daemon::isMode()) { Worker\IPC::SetJobState(false); @@ -1246,9 +1249,9 @@ class Worker $priority = self::PRIORITY_MEDIUM; // Don't fork from frontend tasks by default - $dont_fork = DI::config()->get('system', 'worker_dont_fork', false) || !DI::mode()->isBackend(); - $created = DateTimeFormat::utcNow(); - $delayed = DBA::NULL_DATETIME; + $dont_fork = DI::config()->get('system', 'worker_dont_fork', false) || !DI::mode()->isBackend(); + $created = DateTimeFormat::utcNow(); + $delayed = DBA::NULL_DATETIME; $force_priority = false; $run_parameter = array_shift($args); @@ -1275,10 +1278,10 @@ class Worker throw new \InvalidArgumentException('Priority number or task parameter array expected as first argument'); } - $command = array_shift($args); + $command = array_shift($args); $parameters = json_encode($args); - $queue = DBA::selectFirst('workerqueue', ['id', 'priority'], ['command' => $command, 'parameter' => $parameters, 'done' => false]); - $added = 0; + $queue = DBA::selectFirst('workerqueue', ['id', 'priority'], ['command' => $command, 'parameter' => $parameters, 'done' => false]); + $added = 0; if (!is_int($priority) || !in_array($priority, self::PRIORITIES)) { Logger::warning('Invalid priority', ['priority' => $priority, 'command' => $command]); @@ -1292,7 +1295,7 @@ class Worker if (empty($queue)) { if (!DBA::insert('workerqueue', ['command' => $command, 'parameter' => $parameters, 'created' => $created, - 'priority' => $priority, 'next_try' => $delayed])) { + 'priority' => $priority, 'next_try' => $delayed])) { return 0; } $added = DBA::lastInsertId(); @@ -1354,11 +1357,11 @@ class Worker */ private static function getNextRetrial(array $queue, int $max_level): int { - $created = strtotime($queue['created']); + $created = strtotime($queue['created']); $retrial_time = time() - $created; $new_retrial = $queue['retrial'] + 1; - $total = 0; + $total = 0; for ($retrial = 0; $retrial <= $max_level + 1; ++$retrial) { $delay = (($retrial + 3) ** 4) + (rand(1, 30) * ($retrial + 1)); $total += $delay; @@ -1396,7 +1399,7 @@ class Worker return false; } - $id = $queue['id']; + $id = $queue['id']; $priority = $queue['priority']; $max_level = DI::config()->get('system', 'worker_defer_limit'); @@ -1414,7 +1417,7 @@ class Worker // Calculate the delay until the next trial $delay = (($new_retrial + 2) ** 4) + (rand(1, 30) * ($new_retrial)); - $next = DateTimeFormat::utc('now + ' . $delay . ' seconds'); + $next = DateTimeFormat::utc('now + ' . $delay . ' seconds'); if (($priority < self::PRIORITY_MEDIUM) && ($new_retrial > 3)) { $priority = self::PRIORITY_MEDIUM; @@ -1426,7 +1429,7 @@ class Worker Logger::info('Deferred task', ['id' => $id, 'retrial' => $new_retrial, 'created' => $queue['created'], 'next_execution' => $next, 'old_prio' => $queue['priority'], 'new_prio' => $priority]); - $stamp = (float)microtime(true); + $stamp = (float)microtime(true); $fields = ['retrial' => $new_retrial, 'next_try' => $next, 'executed' => DBA::NULL_DATETIME, 'pid' => 0, 'priority' => $priority]; DBA::update('workerqueue', $fields, ['id' => $id]); self::$db_duration += (microtime(true) - $stamp); @@ -1445,7 +1448,7 @@ class Worker { // 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; + $end = strtotime(DI::config()->get('system', 'maintenance_end')) % 86400; Logger::info('Maintenance window', ['start' => date('H:i:s', $start), 'end' => date('H:i:s', $end)]); diff --git a/src/Core/Worker/Daemon.php b/src/Core/Worker/Daemon.php index dffaae2aca..ee5f7a98ae 100644 --- a/src/Core/Worker/Daemon.php +++ b/src/Core/Worker/Daemon.php @@ -115,7 +115,7 @@ class Daemon private static function spawn() { Logger::notice('Starting new daemon process'); - DI::system()->run('bin/daemon.php', ['start']); + DI::system()->run('bin/console.php', ['start']); Logger::notice('New daemon process started'); } } diff --git a/tests/Unit/AppTest.php b/tests/Unit/AppTest.php index 124e63472a..38c53423dc 100644 --- a/tests/Unit/AppTest.php +++ b/tests/Unit/AppTest.php @@ -5,22 +5,22 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -declare(strict_types = 1); +declare(strict_types=1); namespace Friendica\Test\Unit; -use Dice\Dice; use Friendica\App; +use Friendica\Core\Container; use PHPUnit\Framework\TestCase; class AppTest extends TestCase { - public function testFromDiceReturnsApp(): void + public function testFromContainerReturnsApp(): void { - $dice = $this->createMock(Dice::class); - $dice->expects($this->never())->method('create'); + $container = $this->createMock(Container::class); + $container->expects($this->never())->method('create'); - $app = App::fromDice($dice); + $app = App::fromContainer($container); $this->assertInstanceOf(App::class, $app); } diff --git a/tests/Unit/Core/ContainerTest.php b/tests/Unit/Core/ContainerTest.php new file mode 100644 index 0000000000..bb5ccda398 --- /dev/null +++ b/tests/Unit/Core/ContainerTest.php @@ -0,0 +1,48 @@ +createMock(Dice::class); + $dice->expects($this->never())->method('create'); + + $container = Container::fromDice($dice); + + $this->assertInstanceOf(Container::class, $container); + } + + public function testCreateFromContainer(): void + { + $dice = $this->createMock(Dice::class); + $dice->expects($this->once())->method('create')->with(LoggerInterface::class)->willReturn(new NullLogger()); + + $container = Container::fromDice($dice); + + $this->assertInstanceOf(NullLogger::class, $container->create(LoggerInterface::class)); + } + + public function testAddRuleFromContainer(): void + { + $dice = $this->createMock(Dice::class); + $dice->expects($this->once())->method('addRule')->with(LoggerInterface::class, ['constructParams' => ['console']])->willReturn($dice); + + $container = Container::fromDice($dice); + $container->addRule(LoggerInterface::class, ['constructParams' => ['console']]); + } +}