-
Notifications
You must be signed in to change notification settings - Fork 302
/
Copy pathInteractsWithServers.php
160 lines (137 loc) · 4.21 KB
/
InteractsWithServers.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
namespace Laravel\Octane\Commands\Concerns;
use InvalidArgumentException;
use Laravel\Octane\Exceptions\ServerShutdownException;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\Process;
trait InteractsWithServers
{
/**
* Run the given server process.
*
* @param \Symfony\Component\Process\Process $server
* @param \Laravel\Octane\Contracts\ServerProcessInspector $inspector
* @param string $type
* @return int
*/
protected function runServer($server, $inspector, $type)
{
while (! $server->isStarted()) {
sleep(1);
}
$this->writeServerRunningMessage();
$watcher = $this->startServerWatcher();
try {
while ($server->isRunning()) {
$this->writeServerOutput($server);
if ($watcher->isRunning() &&
$watcher->getIncrementalOutput()) {
$this->info('Application change detected. Restarting workers…');
$inspector->reloadServer();
} elseif ($watcher->isTerminated()) {
$this->error(
'Watcher process has terminated. Please ensure Node and chokidar are installed.'.PHP_EOL.
$watcher->getErrorOutput()
);
return 1;
}
usleep(500 * 1000);
}
$this->writeServerOutput($server);
} catch (ServerShutdownException) {
return 1;
} finally {
$this->stopServer();
}
return $server->getExitCode();
}
/**
* Start the watcher process for the server.
*
* @return \Symfony\Component\Process\Process|object
*/
protected function startServerWatcher()
{
if (! $this->option('watch')) {
return new class
{
public function __call($method, $parameters)
{
return null;
}
};
}
if (empty($paths = config('octane.watch'))) {
throw new InvalidArgumentException(
'List of directories/files to watch not found. Please update your "config/octane.php" configuration file.',
);
}
return tap(new Process([
(new ExecutableFinder)->find('node'),
'file-watcher.cjs',
json_encode(collect(config('octane.watch'))->map(fn ($path) => base_path($path))),
$this->option('poll'),
], realpath(__DIR__.'/../../../bin'), null, null, null))->start();
}
/**
* Write the server start "message" to the console.
*
* @return void
*/
protected function writeServerRunningMessage()
{
$this->info('Server running…');
$this->output->writeln([
'',
' Local: <fg=white;options=bold>http://'.$this->getHost().':'.$this->getPort().' </>',
'',
' <fg=yellow>Press Ctrl+C to stop the server</>',
'',
]);
}
/**
* Retrieve the given server output and flush it.
*
* @return array
*/
protected function getServerOutput($server)
{
return tap([
$server->getIncrementalOutput(),
$server->getIncrementalErrorOutput(),
], fn () => $server->clearOutput()->clearErrorOutput());
}
/**
* Get the Octane HTTP server host IP to bind on.
*
* @return string
*/
protected function getHost()
{
return $this->option('host') ?? config('octane.host') ?? $_ENV['OCTANE_HOST'] ?? '127.0.0.1';
}
/**
* Get the Octane HTTP server port.
*
* @return string
*/
protected function getPort()
{
return $this->option('port') ?? config('octane.port') ?? $_ENV['OCTANE_PORT'] ?? '8000';
}
/**
* Returns the list of signals to subscribe.
*/
public function getSubscribedSignals(): array
{
return [SIGINT, SIGTERM];
}
/**
* The method will be called when the application is signaled.
*/
public function handleSignal(int $signal): void
{
$this->stopServer();
exit(0);
}
}