$value) { putenv($key.'='.$value); $_ENV[$key] = $_SERVER[$key] = $value; } // This helper deliberately excludes the SGF composition and its production connection. putenv('SGC_PRODUCT_COMPOSITION=sgc'); $_ENV['SGC_PRODUCT_COMPOSITION'] = $_SERVER['SGC_PRODUCT_COMPOSITION'] = 'sgc'; $daemon = in_array('--daemon', $argv, true); $lock = fopen($root.'/storage/framework/replenishment-evaluation.lock', 'c'); if ($lock === false) { throw new RuntimeException('Não foi possível abrir o controlo da verificação periódica.'); } if (! flock($lock, LOCK_EX | LOCK_NB)) { fwrite(STDOUT, "Verificação periódica já em execução.\n"); if (! $daemon) { exit(0); } // Standby until the running helper exits; never run two local schedulers together. if (! flock($lock, LOCK_EX)) { throw new RuntimeException('Não foi possível acompanhar o verificador existente.'); } } do { $started = gmdate('c'); $process = new Process([PHP_BINARY, 'artisan', 'sgc:replenishment-tick'], $root, timeout: 55); $process->run(); // Deliberately no raw exception/configuration content in the public status evidence. $status = ['started_at' => $started, 'finished_at' => gmdate('c'), 'pid' => getmypid(), 'scope' => 'SGC evaluation 8005', 'result' => $process->isSuccessful() ? 'passed' : 'retry_pending', 'exit_code' => $process->getExitCode()]; $temporary = $root.'/storage/framework/replenishment-status.tmp'; file_put_contents($temporary, json_encode($status, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); rename($temporary, $root.'/storage/framework/replenishment-status.json'); fwrite(STDOUT, json_encode($status, JSON_THROW_ON_ERROR)."\n"); if (! $daemon) { flock($lock, LOCK_UN); fclose($lock); exit($process->isSuccessful() ? 0 : 1); } // Technical poll every minute; each work item has its own persisted next run time. sleep(60); } while (true);