Skip to content

Commit 5cd9643

Browse files
authored
Handle SIGTERM/SIGINT in StartCommand for graceful shutdown (#22)
1 parent ff4773b commit 5cd9643

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/Console/StartCommand.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ class StartCommand extends Command
3434
/**
3535
* Execute the console command.
3636
*/
37-
public function handle()
37+
public function handle(): int
3838
{
39+
$this->listenForSignals();
40+
3941
$keepUp = $this->option('reset') ? false : true;
4042
$trigger = Trigger::replication($this->option('replication'));
4143

@@ -91,5 +93,34 @@ public function handle()
9193

9294
goto start;
9395
}
96+
97+
return Command::SUCCESS;
98+
}
99+
100+
/**
101+
* Register SIGTERM/SIGINT handlers for immediate shutdown.
102+
*
103+
* The start() method blocks inside MySQLReplicationFactory::run() reading
104+
* from a socket. Setting a flag is insufficient because the blocking read
105+
* never returns to check it. We must exit directly from the signal handler,
106+
* matching the pattern used by the library's own Terminate subscriber.
107+
*/
108+
protected function listenForSignals(): void
109+
{
110+
if (! function_exists('pcntl_async_signals') || ! function_exists('pcntl_signal')) {
111+
return;
112+
}
113+
114+
pcntl_async_signals(true);
115+
116+
$handler = function (int $signal) {
117+
$name = $signal === SIGTERM ? 'SIGTERM' : 'SIGINT';
118+
$this->info("Received {$name}, shutting down...");
119+
120+
exit(0);
121+
};
122+
123+
pcntl_signal(SIGTERM, $handler);
124+
pcntl_signal(SIGINT, $handler);
94125
}
95126
}

0 commit comments

Comments
 (0)