81 lines
2.7 KiB
PHP
81 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Workerman\Timer;
|
|
use Workerman\Worker;
|
|
|
|
/**
|
|
* Long-lived Workerman process for AI queues (content polish + comment moderation).
|
|
*
|
|
* This is separate from `queue:ai`, which is a short-lived Laravel `queue:work`
|
|
* helper for local/dev. Production usually runs either this command OR a
|
|
* dedicated `queue:work` on the AI queues — not both.
|
|
*/
|
|
class WorkermanAiCommand extends Command
|
|
{
|
|
protected $signature = 'workerman:ai
|
|
{action=start : start|stop|restart|reload|status|connections}
|
|
{--count=1 : Worker processes}
|
|
{--d : Daemonize (pass through to Workerman)}';
|
|
|
|
protected $description = 'Workerman long-running AI queue consumer (ai-content, ai-moderation). Not started by queue:ai.';
|
|
|
|
public function handle(): int
|
|
{
|
|
if (! extension_loaded('pcntl') || ! extension_loaded('posix')) {
|
|
$this->error('workerman:ai requires the pcntl and posix PHP extensions (Linux/macOS CLI).');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$action = (string) $this->argument('action');
|
|
$allowed = ['start', 'stop', 'restart', 'reload', 'status', 'connections'];
|
|
|
|
if (! in_array($action, $allowed, true)) {
|
|
$this->error('Unknown action. Use: '.implode('|', $allowed));
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
// Workerman treats `artisan` as the start file, so unset paths default
|
|
// to the project root (workerman.log / workerman.artisan.status).
|
|
$runtime = storage_path('logs');
|
|
if (! is_dir($runtime)) {
|
|
mkdir($runtime, 0775, true);
|
|
}
|
|
|
|
Worker::$command = $action.($this->option('d') ? ' -d' : '');
|
|
Worker::$pidFile = $runtime.'/workerman-ai.pid';
|
|
Worker::$logFile = $runtime.'/workerman-ai.log';
|
|
Worker::$statusFile = $runtime.'/workerman-ai.status';
|
|
Worker::$stdoutFile = $runtime.'/workerman-ai.stdout.log';
|
|
|
|
$this->info("Workerman AI: {$action} (queues: ai-content, ai-moderation)");
|
|
|
|
$worker = new Worker;
|
|
$worker->count = max(1, (int) $this->option('count'));
|
|
$worker->name = 'larablog-ai';
|
|
|
|
$worker->onWorkerStart = function () {
|
|
Timer::add(1, function () {
|
|
Artisan::call('queue:work', [
|
|
'--queue' => 'ai-content,ai-moderation',
|
|
'--stop-when-empty' => true,
|
|
'--max-time' => 50,
|
|
'--sleep' => 1,
|
|
'--tries' => 3,
|
|
]);
|
|
});
|
|
};
|
|
|
|
Worker::runAll();
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|