13
13
use SwooleTW \Http \HotReload \FSOutput ;
14
14
use SwooleTW \Http \HotReload \FSProcess ;
15
15
use SwooleTW \Http \Server \AccessOutput ;
16
+ use SwooleTW \Http \Server \PidManager ;
16
17
use SwooleTW \Http \Middleware \AccessLog ;
17
18
use SwooleTW \Http \Server \Facades \Server ;
18
19
use Illuminate \Contracts \Container \Container ;
@@ -59,6 +60,25 @@ class HttpServerCommand extends Command
59
60
*/
60
61
protected $ config ;
61
62
63
+ /**
64
+ * A manager to handle pid about the application.
65
+ *
66
+ * @var PidManager
67
+ */
68
+ protected $ pidManager ;
69
+
70
+ /**
71
+ * Create a an new HttpServerCommand instance.
72
+ *
73
+ * @param PidManager $pidManager
74
+ */
75
+ public function __construct (PidManager $ pidManager )
76
+ {
77
+ parent ::__construct ();
78
+
79
+ $ this ->pidManager = $ pidManager ;
80
+ }
81
+
62
82
/**
63
83
* Execute the console command.
64
84
*
@@ -93,7 +113,7 @@ protected function runAction()
93
113
*/
94
114
protected function start ()
95
115
{
96
- if ($ this ->isRunning ($ this -> getCurrentPid () )) {
116
+ if ($ this ->isRunning ()) {
97
117
$ this ->error ('Failed! swoole_http_server process is already running. ' );
98
118
99
119
return ;
@@ -132,17 +152,15 @@ protected function start()
132
152
*/
133
153
protected function stop ()
134
154
{
135
- $ pid = $ this ->getCurrentPid ();
136
-
137
- if (! $ this ->isRunning ($ pid )) {
155
+ if (! $ this ->isRunning ()) {
138
156
$ this ->error ("Failed! There is no swoole_http_server process running. " );
139
157
140
158
return ;
141
159
}
142
160
143
161
$ this ->info ('Stopping swoole http server... ' );
144
162
145
- $ isRunning = $ this ->killProcess ($ pid , SIGTERM , 15 );
163
+ $ isRunning = $ this ->killProcess (SIGTERM , 15 );
146
164
147
165
if ($ isRunning ) {
148
166
$ this ->error ('Unable to stop the swoole_http_server process. ' );
@@ -152,7 +170,7 @@ protected function stop()
152
170
153
171
// I don't known why Swoole didn't trigger "onShutdown" after sending SIGTERM.
154
172
// So we should manually remove the pid file.
155
- $ this ->removePidFile ();
173
+ $ this ->pidManager -> delete ();
156
174
157
175
$ this ->info ('> success ' );
158
176
}
@@ -162,9 +180,7 @@ protected function stop()
162
180
*/
163
181
protected function restart ()
164
182
{
165
- $ pid = $ this ->getCurrentPid ();
166
-
167
- if ($ this ->isRunning ($ pid )) {
183
+ if ($ this ->isRunning ()) {
168
184
$ this ->stop ();
169
185
}
170
186
@@ -176,19 +192,15 @@ protected function restart()
176
192
*/
177
193
protected function reload ()
178
194
{
179
- $ pid = $ this ->getCurrentPid ();
180
-
181
- if (! $ this ->isRunning ($ pid )) {
195
+ if (! $ this ->isRunning ()) {
182
196
$ this ->error ("Failed! There is no swoole_http_server process running. " );
183
197
184
198
return ;
185
199
}
186
200
187
201
$ this ->info ('Reloading swoole_http_server... ' );
188
202
189
- $ isRunning = $ this ->killProcess ($ pid , SIGUSR1 );
190
-
191
- if (! $ isRunning ) {
203
+ if (! $ this ->killProcess (SIGUSR1 )) {
192
204
$ this ->error ('> failure ' );
193
205
194
206
return ;
@@ -210,8 +222,7 @@ protected function infos()
210
222
*/
211
223
protected function showInfos ()
212
224
{
213
- $ pid = $ this ->getCurrentPid ();
214
- $ isRunning = $ this ->isRunning ($ pid );
225
+ $ isRunning = $ this ->isRunning ();
215
226
$ host = Arr::get ($ this ->config , 'server.host ' );
216
227
$ port = Arr::get ($ this ->config , 'server.port ' );
217
228
$ reactorNum = Arr::get ($ this ->config , 'server.options.reactor_num ' );
@@ -231,7 +242,7 @@ protected function showInfos()
231
242
['Worker Num ' , $ workerNum ],
232
243
['Task Worker Num ' , $ isWebsocket ? $ taskWorkerNum : 0 ],
233
244
['Websocket Mode ' , $ isWebsocket ? 'On ' : 'Off ' ],
234
- ['PID ' , $ isRunning ? $ pid : 'None ' ],
245
+ ['PID ' , $ isRunning ? implode ( ' , ' , $ this -> pidManager -> read ()) : 'None ' ],
235
246
['Log Path ' , $ logFile ],
236
247
];
237
248
@@ -281,83 +292,53 @@ protected function getHotReloadProcess($server)
281
292
*
282
293
* @return bool
283
294
*/
284
- protected function isRunning ($ pid )
295
+ public function isRunning ()
285
296
{
286
- if (! $ pid ) {
297
+ $ pids = $ this ->pidManager ->read ();
298
+
299
+ if ([] === $ pids ) {
287
300
return false ;
288
301
}
289
302
290
- try {
291
- return Process::kill ($ pid , 0 );
292
- } catch (Throwable $ e ) {
293
- return false ;
303
+ [$ masterPid , $ managerPid ] = $ pids ;
304
+
305
+ if ($ managerPid ) {
306
+ // Swoole process mode
307
+ return $ masterPid && $ managerPid && Process::kill ((int ) $ managerPid , 0 );
294
308
}
309
+
310
+ // Swoole base mode, no manager process
311
+ return $ masterPid && Process::kill ((int ) $ masterPid , 0 );
295
312
}
296
313
297
314
/**
298
315
* Kill process.
299
316
*
300
- * @param int $pid
301
317
* @param int $sig
302
318
* @param int $wait
303
319
*
304
320
* @return bool
305
321
*/
306
- protected function killProcess ($ pid , $ sig , $ wait = 0 )
322
+ protected function killProcess ($ sig , $ wait = 0 )
307
323
{
308
- Process::kill ($ pid , $ sig );
324
+ Process::kill (
325
+ Arr::first ($ this ->pidManager ->read ()),
326
+ $ sig
327
+ );
309
328
310
329
if ($ wait ) {
311
330
$ start = time ();
312
331
313
332
do {
314
- if (! $ this ->isRunning ($ pid )) {
333
+ if (! $ this ->isRunning ()) {
315
334
break ;
316
335
}
317
336
318
337
usleep (100000 );
319
338
} while (time () < $ start + $ wait );
320
339
}
321
340
322
- return $ this ->isRunning ($ pid );
323
- }
324
-
325
- /**
326
- * Get pid.
327
- *
328
- * @return int|null
329
- */
330
- protected function getCurrentPid ()
331
- {
332
- if ($ this ->currentPid ) {
333
- return $ this ->currentPid ;
334
- }
335
-
336
- $ path = $ this ->getPidPath ();
337
-
338
- return $ this ->currentPid = file_exists ($ path )
339
- ? (int ) file_get_contents ($ path ) ?? $ this ->removePidFile ()
340
- : null ;
341
- }
342
-
343
- /**
344
- * Get Pid file path.
345
- *
346
- * @return string
347
- */
348
- protected function getPidPath ()
349
- {
350
- return Arr::get ($ this ->config , 'server.options.pid_file ' , storage_path ('logs/swoole.pid ' ));
351
- }
352
-
353
- /**
354
- * Remove Pid file.
355
- */
356
- protected function removePidFile ()
357
- {
358
- if (file_exists ($ this ->getPidPath ())) {
359
- unlink ($ this ->getPidPath ());
360
- }
341
+ return $ this ->isRunning ();
361
342
}
362
343
363
344
/**
0 commit comments