@@ -55,35 +55,20 @@ public function start(MasterProcess $masterProcess, Suspension $suspension): voi
55
55
$ this ->workerRelay = new Relay ($ masterPipe );
56
56
$ this ->serverStatus ->subscribeToWorkerMessages ($ this ->workerRelay );
57
57
58
- EventLoop::getDriver ()->onChildProcessExit ($ this ->onChildStop (...));
59
- EventLoop::repeat (WorkerProcess::HEARTBEAT_PERIOD , fn () => $ this ->monitorWorkerStatus ());
60
-
58
+ $ this ->watchChildProcesses ();
61
59
$ this ->spawnWorkers ();
62
60
}
63
61
64
- public function stop (): Future
62
+ public function watchChildProcesses (): void
65
63
{
66
- $ this ->stopFuture = new DeferredFuture ();
67
-
68
- foreach ($ this ->workerPool ->getAlivePids () as $ pid ) {
69
- \posix_kill ($ pid , SIGTERM );
70
- }
71
-
72
- if ($ this ->workerPool ->getWorkerCount () === 0 ) {
73
- $ this ->stopFuture ->complete ();
74
- } else {
75
- EventLoop::delay ($ this ->stopTimeout , function (): void {
76
- // Send SIGKILL signal to all child processes ater timeout
77
- foreach ($ this ->workerPool ->getAlivePids () as $ pid ) {
78
- \posix_kill ($ pid , SIGKILL );
79
- $ worker = $ this ->workerPool ->getWorkerByPid ($ pid );
80
- $ this ->logger ->notice (\sprintf ('Worker %s[pid:%s] killed after %ss timeout ' , $ worker ->name , $ pid , $ this ->stopTimeout ));
81
- }
82
- $ this ->stopFuture ->complete ();
83
- });
84
- }
64
+ EventLoop::onSignal (SIGCHLD , function () {
65
+ while (($ pid = \pcntl_wait ($ status , WNOHANG )) > 0 ) {
66
+ $ exitCode = \pcntl_wexitstatus ($ status ) ?: 0 ;
67
+ $ this ->onChildStop ($ pid , $ exitCode );
68
+ }
69
+ });
85
70
86
- return $ this ->stopFuture -> getFuture ( );
71
+ EventLoop:: repeat (WorkerProcess:: HEARTBEAT_PERIOD , fn () => $ this ->monitorWorkerStatus () );
87
72
}
88
73
89
74
private function spawnWorkers (): void
@@ -156,6 +141,31 @@ private function onChildStop(int $pid, int $exitCode): void
156
141
}
157
142
}
158
143
144
+ public function stop (): Future
145
+ {
146
+ $ this ->stopFuture = new DeferredFuture ();
147
+
148
+ foreach ($ this ->workerPool ->getAlivePids () as $ pid ) {
149
+ \posix_kill ($ pid , SIGTERM );
150
+ }
151
+
152
+ if ($ this ->workerPool ->getWorkerCount () === 0 ) {
153
+ $ this ->stopFuture ->complete ();
154
+ } else {
155
+ EventLoop::delay ($ this ->stopTimeout , function (): void {
156
+ // Send SIGKILL signal to all child processes ater timeout
157
+ foreach ($ this ->workerPool ->getAlivePids () as $ pid ) {
158
+ \posix_kill ($ pid , SIGKILL );
159
+ $ worker = $ this ->workerPool ->getWorkerByPid ($ pid );
160
+ $ this ->logger ->notice (\sprintf ('Worker %s[pid:%s] killed after %ss timeout ' , $ worker ->name , $ pid , $ this ->stopTimeout ));
161
+ }
162
+ $ this ->stopFuture ->complete ();
163
+ });
164
+ }
165
+
166
+ return $ this ->stopFuture ->getFuture ();
167
+ }
168
+
159
169
public function reload (): void
160
170
{
161
171
foreach ($ this ->workerPool ->getAlivePids () as $ pid ) {
0 commit comments