Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.

Commit 277d4a4

Browse files
authored
Merge pull request #271 from lilianjin/master
Refactoring pid manager
2 parents d7249f9 + 149ea79 commit 277d4a4

File tree

9 files changed

+243
-129
lines changed

9 files changed

+243
-129
lines changed

src/Commands/HttpServerCommand.php

Lines changed: 48 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use SwooleTW\Http\HotReload\FSOutput;
1414
use SwooleTW\Http\HotReload\FSProcess;
1515
use SwooleTW\Http\Server\AccessOutput;
16+
use SwooleTW\Http\Server\PidManager;
1617
use SwooleTW\Http\Middleware\AccessLog;
1718
use SwooleTW\Http\Server\Facades\Server;
1819
use Illuminate\Contracts\Container\Container;
@@ -59,6 +60,25 @@ class HttpServerCommand extends Command
5960
*/
6061
protected $config;
6162

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+
6282
/**
6383
* Execute the console command.
6484
*
@@ -93,7 +113,7 @@ protected function runAction()
93113
*/
94114
protected function start()
95115
{
96-
if ($this->isRunning($this->getCurrentPid())) {
116+
if ($this->isRunning()) {
97117
$this->error('Failed! swoole_http_server process is already running.');
98118

99119
return;
@@ -132,17 +152,15 @@ protected function start()
132152
*/
133153
protected function stop()
134154
{
135-
$pid = $this->getCurrentPid();
136-
137-
if (! $this->isRunning($pid)) {
155+
if (! $this->isRunning()) {
138156
$this->error("Failed! There is no swoole_http_server process running.");
139157

140158
return;
141159
}
142160

143161
$this->info('Stopping swoole http server...');
144162

145-
$isRunning = $this->killProcess($pid, SIGTERM, 15);
163+
$isRunning = $this->killProcess(SIGTERM, 15);
146164

147165
if ($isRunning) {
148166
$this->error('Unable to stop the swoole_http_server process.');
@@ -152,7 +170,7 @@ protected function stop()
152170

153171
// I don't known why Swoole didn't trigger "onShutdown" after sending SIGTERM.
154172
// So we should manually remove the pid file.
155-
$this->removePidFile();
173+
$this->pidManager->delete();
156174

157175
$this->info('> success');
158176
}
@@ -162,9 +180,7 @@ protected function stop()
162180
*/
163181
protected function restart()
164182
{
165-
$pid = $this->getCurrentPid();
166-
167-
if ($this->isRunning($pid)) {
183+
if ($this->isRunning()) {
168184
$this->stop();
169185
}
170186

@@ -176,19 +192,15 @@ protected function restart()
176192
*/
177193
protected function reload()
178194
{
179-
$pid = $this->getCurrentPid();
180-
181-
if (! $this->isRunning($pid)) {
195+
if (! $this->isRunning()) {
182196
$this->error("Failed! There is no swoole_http_server process running.");
183197

184198
return;
185199
}
186200

187201
$this->info('Reloading swoole_http_server...');
188202

189-
$isRunning = $this->killProcess($pid, SIGUSR1);
190-
191-
if (! $isRunning) {
203+
if (! $this->killProcess(SIGUSR1)) {
192204
$this->error('> failure');
193205

194206
return;
@@ -210,8 +222,7 @@ protected function infos()
210222
*/
211223
protected function showInfos()
212224
{
213-
$pid = $this->getCurrentPid();
214-
$isRunning = $this->isRunning($pid);
225+
$isRunning = $this->isRunning();
215226
$host = Arr::get($this->config, 'server.host');
216227
$port = Arr::get($this->config, 'server.port');
217228
$reactorNum = Arr::get($this->config, 'server.options.reactor_num');
@@ -231,7 +242,7 @@ protected function showInfos()
231242
['Worker Num', $workerNum],
232243
['Task Worker Num', $isWebsocket ? $taskWorkerNum : 0],
233244
['Websocket Mode', $isWebsocket ? 'On' : 'Off'],
234-
['PID', $isRunning ? $pid : 'None'],
245+
['PID', $isRunning ? implode(', ', $this->pidManager->read()) : 'None'],
235246
['Log Path', $logFile],
236247
];
237248

@@ -281,83 +292,53 @@ protected function getHotReloadProcess($server)
281292
*
282293
* @return bool
283294
*/
284-
protected function isRunning($pid)
295+
public function isRunning()
285296
{
286-
if (! $pid) {
297+
$pids = $this->pidManager->read();
298+
299+
if ([] === $pids) {
287300
return false;
288301
}
289302

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);
294308
}
309+
310+
// Swoole base mode, no manager process
311+
return $masterPid && Process::kill((int) $masterPid, 0);
295312
}
296313

297314
/**
298315
* Kill process.
299316
*
300-
* @param int $pid
301317
* @param int $sig
302318
* @param int $wait
303319
*
304320
* @return bool
305321
*/
306-
protected function killProcess($pid, $sig, $wait = 0)
322+
protected function killProcess($sig, $wait = 0)
307323
{
308-
Process::kill($pid, $sig);
324+
Process::kill(
325+
Arr::first($this->pidManager->read()),
326+
$sig
327+
);
309328

310329
if ($wait) {
311330
$start = time();
312331

313332
do {
314-
if (! $this->isRunning($pid)) {
333+
if (! $this->isRunning()) {
315334
break;
316335
}
317336

318337
usleep(100000);
319338
} while (time() < $start + $wait);
320339
}
321340

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();
361342
}
362343

363344
/**

src/HttpServiceProvider.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
namespace SwooleTW\Http;
44

5-
use SwooleTW\Http\Helpers\FW;
5+
use Illuminate\Database\DatabaseManager;
66
use Illuminate\Queue\QueueManager;
7-
use Swoole\Http\Server as HttpServer;
87
use Illuminate\Support\ServiceProvider;
9-
use SwooleTW\Http\Server\Facades\Server;
10-
use Illuminate\Database\DatabaseManager;
11-
use SwooleTW\Http\Coroutine\MySqlConnection;
128
use SwooleTW\Http\Commands\HttpServerCommand;
13-
use Swoole\Websocket\Server as WebsocketServer;
14-
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;
159
use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory;
10+
use SwooleTW\Http\Coroutine\MySqlConnection;
11+
use SwooleTW\Http\Helpers\FW;
12+
use SwooleTW\Http\Server\Facades\Server;
13+
use SwooleTW\Http\Server\PidManager;
14+
use SwooleTW\Http\Server\PidManagerFactory;
15+
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;
16+
use Swoole\Http\Server as HttpServer;
17+
use Swoole\Websocket\Server as WebsocketServer;
1618

1719
/**
1820
* @codeCoverageIgnore
@@ -43,6 +45,7 @@ abstract class HttpServiceProvider extends ServiceProvider
4345
*/
4446
public function register()
4547
{
48+
$this->registerPidManager();
4649
$this->mergeConfigs();
4750
$this->setIsWebsocket();
4851
$this->registerServer();
@@ -106,6 +109,18 @@ protected function mergeConfigs()
106109
$this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket');
107110
}
108111

112+
/**
113+
* Register pid manager.
114+
*
115+
* @return void
116+
*/
117+
protected function registerPidManager(): void
118+
{
119+
$this->app->singleton(PidManager::class, function() {
120+
return call_user_func(new PidManagerFactory, $this->app);
121+
});
122+
}
123+
109124
/**
110125
* Set isWebsocket.
111126
*/

src/LaravelServiceProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace SwooleTW\Http;
44

5-
use SwooleTW\Http\Server\Manager;
65
use Illuminate\Contracts\Http\Kernel;
76
use SwooleTW\Http\Middleware\AccessLog;
7+
use SwooleTW\Http\Server\Manager;
8+
use SwooleTW\Http\Server\PidManager;
89

910
/**
1011
* @codeCoverageIgnore
@@ -19,7 +20,7 @@ class LaravelServiceProvider extends HttpServiceProvider
1920
protected function registerManager()
2021
{
2122
$this->app->singleton(Manager::class, function ($app) {
22-
return new Manager($app, 'laravel');
23+
return new Manager($app, 'laravel', base_path(), $this->app[PidManager::class]);
2324
});
2425

2526
$this->app->alias(Manager::class, 'swoole.manager');

src/LumenServiceProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
namespace SwooleTW\Http;
44

5-
use SwooleTW\Http\Server\Manager;
65
use SwooleTW\Http\Middleware\AccessLog;
6+
use SwooleTW\Http\Server\Manager;
7+
use SwooleTW\Http\Server\PidManager;
78

89
/**
910
* @codeCoverageIgnore
@@ -18,7 +19,7 @@ class LumenServiceProvider extends HttpServiceProvider
1819
protected function registerManager()
1920
{
2021
$this->app->singleton(Manager::class, function ($app) {
21-
return new Manager($app, 'lumen');
22+
return new Manager($app, 'lumen', base_path(), $this->app[PidManager::class]);
2223
});
2324

2425
$this->app->alias(Manager::class, 'swoole.manager');

0 commit comments

Comments
 (0)