diff --git a/.do/run-background-tasks.php b/.do/run-background-tasks.php index 5ecd9f0a..c580d125 100644 --- a/.do/run-background-tasks.php +++ b/.do/run-background-tasks.php @@ -2,75 +2,43 @@ declare(strict_types=1); -use React\ChildProcess\Process; +use Omnipedia\BackgroundTasks\WorkerProcess; use React\EventLoop\Loop; require __DIR__ . '/../vendor/autoload.php'; -function worker_process(string $command): void { - - print 'Running: ' . $command . \PHP_EOL; - - $process = new Process($command); - - $process->start(); - - $process->on('exit', function( - ?int $exitCode, $termSignal - ) use ($command): void { - if ($exitCode === null) { - print "Command '$command' terminated with signal: $termSignal"; - } - // print 'Process exited with code ' . $exitCode . \PHP_EOL; - }); - $process->stdout->on('data', function($chunk): void { - print $chunk; - }); - $process->stderr->on('data', function($chunk) use ($command): void { - if (!empty(trim($chunk))) { - print $chunk; - } - }); - // $process->stdout->on('error', function(\Exception $exception) use ($command): void { - // print 'Error: ' . $exception->getMessage(); - // }); - // $process->stderr->on('error', function(\Exception $exception) use ($command): void { - // print 'Error: ' . $exception->getMessage(); - // }); - -} - -$drush = __DIR__ . '/../vendor/bin/drush'; +$drush = \realpath(__DIR__ . '/../vendor/bin/drush'); +/** @var \React\EventLoop\LoopInterface */ $loop = Loop::get(); // Run common tasks immediately. $loop->futureTick(function() { - \worker_process(__DIR__ . '/run-common.sh'); + (new WorkerProcess(__DIR__ . '/run-common.sh'))->start(); }); // Run cron every 15 minutes. $loop->addPeriodicTimer(900, function() use ($drush): void { - \worker_process($drush . ' cron'); + (new WorkerProcess($drush . ' cron'))->start(); }); // Every 5 minutes, process jobs from the image style warmer. $loop->addPeriodicTimer(300, function() use ($drush): void { - \worker_process( + (new WorkerProcess( $drush . ' queue:run image_style_warmer_pregenerator --verbose' - ); + ))->start(); }); // Every 10 minutes, process the wiki page changes queue. $loop->addPeriodicTimer(600, function() use ($drush): void { - \worker_process($drush . ' omnipedia:changes-build --verbose'); + (new WorkerProcess($drush . ' omnipedia:changes-build --verbose'))->start(); }); // Every 10 minutes, process the wiki page CDN warmer queue. $loop->addPeriodicTimer(600, function() use ($drush): void { - \worker_process( + (new WorkerProcess( $drush . ' warmer:enqueue omnipedia_wiki_node_cdn --run-queue --verbose' - ); + ))->start(); }); $loop->run(); diff --git a/composer.json b/composer.json index 7a9641fa..78502bdb 100644 --- a/composer.json +++ b/composer.json @@ -243,6 +243,11 @@ "phpstan/extension-installer": true } }, + "autoload": { + "psr-4": { + "Omnipedia\\" : "src/" + } + }, "extra": { "enable-patching": true, "composer-exit-on-patch-failure": true, diff --git a/src/BackgroundTasks/WorkerProcess.php b/src/BackgroundTasks/WorkerProcess.php new file mode 100644 index 00000000..5613b22d --- /dev/null +++ b/src/BackgroundTasks/WorkerProcess.php @@ -0,0 +1,100 @@ +process = new Process($command); + + } + + /** + * Start the configured process. + */ + public function start(): void { + + print 'Running: ' . $this->process->getCommand() . \PHP_EOL; + + $this->process->start(); + + $this->process->on('exit', [$this, 'onProcessExit']); + + $this->process->stdout->on('data', [$this, 'onStdOutData']); + + $this->process->stderr->on('data', [$this, 'onStdErrData']); + + } + + /** + * Process exit event handler. + * + * @param int|null $exitCode + * + * @param int|null $termSignal + */ + public function onProcessExit(?int $exitCode, ?int $termSignal): void { + + if ($exitCode !== null) { + return; + } + + print \sprintf( + 'Command %s terminated with signal: %s', + $this->process->getCommand(), $termSignal + ); + + } + + /** + * stdout data event handler; prints output. + * + * @param string $chunk + * Output data string/chunk. In other contexts this can also be binary data, + * but in our case we're only expecting a string. + */ + public function onStdOutData(string $chunk): void { + + print $chunk; + + } + + /** + * stderr data event handler; prints output. + * + * @param string $chunk + * Output data string/chunk. In other contexts this can also be binary data, + * but in our case we're only expecting a string. + */ + public function onStdErrData(string $chunk): void { + + if (empty(trim($chunk))) { + return; + } + + print $chunk; + + } + +}