-
-
Notifications
You must be signed in to change notification settings - Fork 161
[Mate] Add command to stop running server #1280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,63 @@ | ||
| #!/usr/bin/env php | ||
| <?php | ||
|
|
||
| include __DIR__ . '/mate.php'; | ||
| /* | ||
| * This script will decide if we should try to keep the process alive or not. | ||
| * When running ./vendor/bin/mate serve --force-keep-alive, it will spawn a child process. | ||
| */ | ||
|
|
||
| $keepAlive = false; | ||
| if (($argv[1] ?? false) === 'serve') { | ||
| $keepAlive = $argv; | ||
| // try to detect "--force-keep-alive | ||
| for ($i = 2; $i < $argc; ++$i) { | ||
| if ($argv[$i] === '--force-keep-alive') { | ||
| unset($keepAlive[$i]); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (false === $keepAlive || $argv === $keepAlive) { | ||
| include __DIR__ . '/mate.php'; | ||
| return; | ||
| } | ||
|
|
||
| // Build the command as an array to avoid shell interpretation | ||
| $command = $keepAlive; | ||
|
|
||
| while (true) { | ||
| // Run child attached to parent's STDIN/STDOUT/STDERR so it can read from STDIN | ||
| // and interact as if it was run directly. | ||
| $descriptorSpec = [ | ||
| 0 => ['file', 'php://stdin', 'r'], | ||
| 1 => ['file', 'php://stdout', 'w'], | ||
| 2 => ['file', 'php://stderr', 'w'], | ||
| ]; | ||
|
|
||
| $process = proc_open($command, $descriptorSpec, $pipes, null, null, [ | ||
| 'bypass_shell' => true, | ||
| ]); | ||
|
|
||
| if (!\is_resource($process)) { | ||
| fwrite(STDERR, "[mate][keep-alive] Failed to start process.\n"); | ||
| exit(70); // EX_SOFTWARE | ||
| } | ||
|
|
||
| // Wait for the process to terminate and get its exit code | ||
| $exitCode = proc_close($process); | ||
|
|
||
| if ($exitCode === 0) { | ||
| fwrite(STDERR, "[mate][keep-alive] Process exited with code 0, restarting...\n"); | ||
| sleep(1); | ||
| continue; | ||
| } | ||
|
|
||
| if ($exitCode >= 129 && $exitCode <= 192) { | ||
| $signal = $exitCode - 128; | ||
| fwrite(STDERR, sprintf("[mate][keep-alive] Process terminated by signal %d (exit %d), not restarting.\n", $signal, $exitCode)); | ||
| } else { | ||
| fwrite(STDERR, sprintf("[mate][keep-alive] Process exited with code %d, not restarting.\n", $exitCode)); | ||
| } | ||
|
|
||
| exit($exitCode); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <[email protected]> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\AI\Mate\Command; | ||
|
|
||
| use Symfony\Component\Console\Attribute\AsCommand; | ||
| use Symfony\Component\Console\Command\Command; | ||
| use Symfony\Component\Console\Input\InputInterface; | ||
| use Symfony\Component\Console\Output\OutputInterface; | ||
| use Symfony\Component\Console\Style\SymfonyStyle; | ||
| use Symfony\Component\Finder\Finder; | ||
|
|
||
| /** | ||
| * Stop all running servers. This will force the AI to restart the server. Can be combined with | ||
| * the "--force-keep-alive" option on the "serve" command to make sure the server is restarted | ||
| * and not killed. | ||
| * | ||
| * @author Tobias Nyholm <[email protected]> | ||
| */ | ||
| #[AsCommand('stop', 'Stop running servers to allow them to be restarted with new configuration')] | ||
| class StopCommand extends Command | ||
| { | ||
| public function __construct(private string $cacheDir) | ||
| { | ||
| parent::__construct(self::getDefaultName()); | ||
| } | ||
|
|
||
| public static function getDefaultName(): string | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Any reason not to use invokable command instead? These static methods are deprecated since 7.3 btw
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. The version constraint has been bumped. I intentionally set that to SF 5.4. I'll make a PR to lower it.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI: #1292 |
||
| { | ||
| return 'stop'; | ||
| } | ||
|
|
||
| public static function getDefaultDescription(): string | ||
| { | ||
| return 'Stop running servers to allow them to be restarted with new configuration'; | ||
| } | ||
|
|
||
| protected function execute(InputInterface $input, OutputInterface $output): int | ||
| { | ||
| $io = new SymfonyStyle($input, $output); | ||
|
|
||
| if (!\function_exists('posix_kill')) { | ||
| $io->error('The "stop" command require the posix php extension.'); | ||
|
|
||
| return Command::FAILURE; | ||
| } | ||
|
|
||
| if (!\defined('SIGUSR1')) { | ||
| $io->error('The "stop" command require the pcntl php extension.'); | ||
|
|
||
| return Command::FAILURE; | ||
| } | ||
|
|
||
| $finder = new Finder(); | ||
| $finder->files() | ||
| ->in($this->cacheDir) | ||
| ->name('server_*.pid'); | ||
|
|
||
| foreach ($finder as $file) { | ||
| $pid = (int) file_get_contents($file->getRealPath()); | ||
| posix_kill($pid, \SIGUSR1); | ||
| } | ||
|
|
||
| return Command::SUCCESS; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.