line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojo::Server::Hypnotoad; |
2
|
1
|
|
|
1
|
|
506
|
use Mojo::Base -base; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
6
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# "Bender: I was God once. |
5
|
|
|
|
|
|
|
# God: Yes, I saw. You were doing well, until everyone died." |
6
|
1
|
|
|
1
|
|
6
|
use Config; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
7
|
1
|
|
|
1
|
|
5
|
use Mojo::File qw(path); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
41
|
|
8
|
1
|
|
|
1
|
|
490
|
use Mojo::Server::Prefork; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
11
|
|
9
|
1
|
|
|
1
|
|
7
|
use Mojo::Util qw(steady_time); |
|
1
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
49
|
|
10
|
1
|
|
|
1
|
|
5
|
use Scalar::Util qw(weaken); |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
1487
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
has prefork => sub { Mojo::Server::Prefork->new(listen => ['http://*:8080']) }; |
13
|
|
|
|
|
|
|
has upgrade_timeout => 180; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub configure { |
16
|
0
|
|
|
0
|
1
|
|
my ($self, $name) = @_; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Hypnotoad settings |
19
|
0
|
|
|
|
|
|
my $prefork = $self->prefork; |
20
|
0
|
|
0
|
|
|
|
my $c = $prefork->app->config($name) // {}; |
21
|
0
|
0
|
|
|
|
|
$self->upgrade_timeout($c->{upgrade_timeout}) if $c->{upgrade_timeout}; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Pre-fork settings |
24
|
0
|
0
|
|
|
|
|
$prefork->reverse_proxy($c->{proxy}) if defined $c->{proxy}; |
25
|
0
|
0
|
|
|
|
|
$prefork->trusted_proxies($c->{trusted_proxies}) if defined $c->{trusted_proxies}; |
26
|
0
|
0
|
|
|
|
|
$prefork->max_clients($c->{clients}) if $c->{clients}; |
27
|
0
|
0
|
|
|
|
|
$prefork->max_requests($c->{requests}) if $c->{requests}; |
28
|
|
|
|
|
|
|
defined $c->{$_} and $prefork->$_($c->{$_}) |
29
|
0
|
|
0
|
|
|
|
for qw(accepts backlog graceful_timeout heartbeat_interval heartbeat_timeout inactivity_timeout keep_alive_timeout), |
30
|
|
|
|
|
|
|
qw(listen pid_file spare workers); |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub run { |
34
|
0
|
|
|
0
|
1
|
|
my ($self, $app) = @_; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# No fork emulation support |
37
|
0
|
0
|
|
|
|
|
_exit('Hypnotoad does not support fork emulation.') if $Config{d_pseudofork}; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# Remember executable and application for later |
40
|
0
|
|
0
|
|
|
|
$ENV{HYPNOTOAD_EXE} ||= $0; |
41
|
0
|
|
0
|
|
|
|
$0 = $ENV{HYPNOTOAD_APP} ||= path($app)->to_abs->to_string; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# This is a production server |
44
|
0
|
|
0
|
|
|
|
$ENV{MOJO_MODE} ||= 'production'; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Clean start (to make sure everything works) |
47
|
0
|
0
|
0
|
|
|
|
die "Can't exec: $!" if !$ENV{HYPNOTOAD_REV}++ && !exec $^X, $ENV{HYPNOTOAD_EXE}; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# Preload application and configure server |
50
|
0
|
|
|
|
|
|
my $prefork = $self->prefork->cleanup(0); |
51
|
0
|
|
|
|
|
|
$app = $prefork->load_app($app); |
52
|
0
|
|
0
|
|
|
|
$app->config->{hypnotoad}{pid_file} //= path($ENV{HYPNOTOAD_APP})->sibling('hypnotoad.pid')->to_string; |
53
|
0
|
|
|
|
|
|
$self->configure('hypnotoad'); |
54
|
0
|
|
|
|
|
|
weaken $self; |
55
|
0
|
|
|
0
|
|
|
$prefork->on(wait => sub { $self->_manage }); |
|
0
|
|
|
|
|
|
|
56
|
0
|
|
|
0
|
|
|
$prefork->on(reap => sub { $self->_cleanup(pop) }); |
|
0
|
|
|
|
|
|
|
57
|
0
|
|
|
0
|
|
|
$prefork->on(finish => sub { $self->_finish }); |
|
0
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# Testing |
60
|
0
|
0
|
|
|
|
|
_exit('Everything looks good!') if $ENV{HYPNOTOAD_TEST}; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# Stop running server |
63
|
0
|
0
|
|
|
|
|
$self->_stop if $ENV{HYPNOTOAD_STOP}; |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# Initiate hot deployment |
66
|
0
|
0
|
|
|
|
|
$self->_hot_deploy unless $ENV{HYPNOTOAD_PID}; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# Daemonize as early as possible (but not for restarts) |
69
|
0
|
|
0
|
0
|
|
|
local $SIG{USR2} = sub { $self->{upgrade} ||= steady_time }; |
|
0
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
|
$prefork->start; |
71
|
0
|
0
|
0
|
|
|
|
$prefork->daemonize if !$ENV{HYPNOTOAD_FOREGROUND} && $ENV{HYPNOTOAD_REV} < 3; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# Start accepting connections |
74
|
0
|
|
|
|
|
|
$prefork->cleanup(1)->run; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub _cleanup { |
78
|
0
|
|
|
0
|
|
|
my ($self, $pid) = @_; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Clean up failed upgrade |
81
|
0
|
0
|
0
|
|
|
|
return unless ($self->{new} || '') eq $pid; |
82
|
0
|
|
|
|
|
|
$self->prefork->app->log->error('Zero downtime software upgrade failed'); |
83
|
0
|
|
|
|
|
|
delete @$self{qw(new upgrade)}; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
0
|
0
|
|
0
|
|
|
sub _exit { say shift and exit 0 } |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub _finish { |
89
|
0
|
|
|
0
|
|
|
my $self = shift; |
90
|
|
|
|
|
|
|
|
91
|
0
|
|
|
|
|
|
$self->{finish} = 1; |
92
|
0
|
0
|
|
|
|
|
return unless my $new = $self->{new}; |
93
|
|
|
|
|
|
|
|
94
|
0
|
|
|
|
|
|
my $prefork = $self->prefork->cleanup(0); |
95
|
0
|
|
|
|
|
|
path($prefork->pid_file)->remove; |
96
|
0
|
|
|
|
|
|
$prefork->ensure_pid_file($new); |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _hot_deploy { |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Make sure server is running |
102
|
0
|
0
|
|
0
|
|
|
return unless my $pid = shift->prefork->check_pid; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# Start hot deployment |
105
|
0
|
|
|
|
|
|
kill 'USR2', $pid; |
106
|
0
|
|
|
|
|
|
_exit("Starting hot deployment for Hypnotoad server $pid."); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _manage { |
110
|
0
|
|
|
0
|
|
|
my $self = shift; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Upgraded (wait for all workers to send a heartbeat) |
113
|
0
|
|
|
|
|
|
my $prefork = $self->prefork; |
114
|
0
|
|
|
|
|
|
my $log = $prefork->app->log; |
115
|
0
|
0
|
0
|
|
|
|
if ($ENV{HYPNOTOAD_PID} && $ENV{HYPNOTOAD_PID} ne $$) { |
116
|
0
|
0
|
|
|
|
|
return unless $prefork->healthy == $prefork->workers; |
117
|
0
|
|
|
|
|
|
$log->info("Upgrade successful, stopping $ENV{HYPNOTOAD_PID}"); |
118
|
0
|
|
|
|
|
|
kill 'QUIT', $ENV{HYPNOTOAD_PID}; |
119
|
|
|
|
|
|
|
} |
120
|
0
|
0
|
0
|
|
|
|
$ENV{HYPNOTOAD_PID} = $$ unless ($ENV{HYPNOTOAD_PID} // '') eq $$; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# Upgrade |
123
|
0
|
0
|
0
|
|
|
|
if ($self->{upgrade} && !$self->{finished}) { |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# Fresh start |
126
|
0
|
|
|
|
|
|
my $ut = $self->upgrade_timeout; |
127
|
0
|
0
|
|
|
|
|
unless ($self->{new}) { |
128
|
0
|
|
|
|
|
|
$log->info("Starting zero downtime software upgrade ($ut seconds)"); |
129
|
0
|
0
|
|
|
|
|
die "Can't fork: $!" unless defined(my $pid = $self->{new} = fork); |
130
|
0
|
0
|
0
|
|
|
|
exec $^X, $ENV{HYPNOTOAD_EXE} or die "Can't exec: $!" unless $pid; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Timeout |
134
|
0
|
0
|
|
|
|
|
kill 'KILL', $self->{new} if $self->{upgrade} + $ut <= steady_time; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub _stop { |
139
|
0
|
0
|
|
0
|
|
|
_exit('Hypnotoad server not running.') unless my $pid = shift->prefork->check_pid; |
140
|
0
|
|
|
|
|
|
kill 'QUIT', $pid; |
141
|
0
|
|
|
|
|
|
_exit("Stopping Hypnotoad server $pid gracefully."); |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
1; |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=encoding utf8 |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head1 NAME |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Mojo::Server::Hypnotoad - A production web serv...ALL GLORY TO THE HYPNOTOAD! |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head1 SYNOPSIS |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
use Mojo::Server::Hypnotoad; |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
my $hypnotoad = Mojo::Server::Hypnotoad->new; |
157
|
|
|
|
|
|
|
$hypnotoad->run('/home/sri/myapp.pl'); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=head1 DESCRIPTION |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
L is a full featured, UNIX optimized, pre-forking non-blocking I/O HTTP and WebSocket server, |
162
|
|
|
|
|
|
|
built around the very well tested and reliable L, with IPv6, TLS, SNI, UNIX domain socket, Comet |
163
|
|
|
|
|
|
|
(long polling), keep-alive, multiple event loop and hot deployment support that just works. Note that the server uses |
164
|
|
|
|
|
|
|
signals for process management, so you should avoid modifying signal handlers in your applications. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
To start applications with it you can use the L script, which listens on port C<8080>, automatically |
167
|
|
|
|
|
|
|
daemonizes the server process and defaults to C mode for L and L |
168
|
|
|
|
|
|
|
applications. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
$ hypnotoad ./myapp.pl |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
You can run the same command again for automatic hot deployment. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
$ hypnotoad ./myapp.pl |
175
|
|
|
|
|
|
|
Starting hot deployment for Hypnotoad server 31841. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
This second invocation will load the application again, detect the process id file with it, and send a L"USR2"> |
178
|
|
|
|
|
|
|
signal to the already running server. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
For better scalability (epoll, kqueue) and to provide non-blocking name resolution, SOCKS5 as well as TLS support, the |
181
|
|
|
|
|
|
|
optional modules L (4.32+), L (0.15+), L (0.64+) and L |
182
|
|
|
|
|
|
|
(2.009+) will be used automatically if possible. Individual features can also be disabled with the C, |
183
|
|
|
|
|
|
|
C and C environment variables. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
See L for more. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=head1 MANAGER SIGNALS |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
The L manager process can be controlled at runtime with the following signals. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 INT, TERM |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Shut down server immediately. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head2 QUIT |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Shut down server gracefully. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head2 TTIN |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Increase worker pool by one. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head2 TTOU |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Decrease worker pool by one. |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=head2 USR2 |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Attempt zero downtime software upgrade (hot deployment) without losing any incoming connections. |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
Manager (old) |
212
|
|
|
|
|
|
|
|- Worker [1] |
213
|
|
|
|
|
|
|
|- Worker [2] |
214
|
|
|
|
|
|
|
|- Worker [3] |
215
|
|
|
|
|
|
|
|- Worker [4] |
216
|
|
|
|
|
|
|
+- Manager (new) |
217
|
|
|
|
|
|
|
|- Worker [1] |
218
|
|
|
|
|
|
|
|- Worker [2] |
219
|
|
|
|
|
|
|
|- Worker [3] |
220
|
|
|
|
|
|
|
+- Worker [4] |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
The new manager will automatically send a L"QUIT"> signal to the old manager and take over serving requests after |
223
|
|
|
|
|
|
|
starting up successfully. |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head1 WORKER SIGNALS |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
L worker processes can be controlled at runtime with the following signals. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head2 QUIT |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
Stop worker gracefully. |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=head1 SETTINGS |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
L can be configured with the following settings, see |
236
|
|
|
|
|
|
|
L for examples. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=head2 accepts |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
accepts => 100 |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
Maximum number of connections a worker is allowed to accept, before stopping gracefully and then getting replaced with |
243
|
|
|
|
|
|
|
a newly started worker, defaults to the value of L. Setting the value to C<0> will |
244
|
|
|
|
|
|
|
allow workers to accept new connections indefinitely. Note that up to half of this value can be subtracted randomly to |
245
|
|
|
|
|
|
|
improve load balancing, and to make sure that not all workers restart at the same time. |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=head2 backlog |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
backlog => 128 |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
Listen backlog size, defaults to the value of L. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=head2 clients |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
clients => 100 |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
Maximum number of accepted connections each worker process is allowed to handle concurrently, before stopping to accept |
258
|
|
|
|
|
|
|
new incoming connections, defaults to the value of L. Note that high concurrency works |
259
|
|
|
|
|
|
|
best with applications that perform mostly non-blocking operations, to optimize for blocking operations you can |
260
|
|
|
|
|
|
|
decrease this value and increase L"workers"> instead for better performance. |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head2 graceful_timeout |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
graceful_timeout => 15 |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
Maximum amount of time in seconds stopping a worker gracefully may take before being forced, defaults to the value of |
267
|
|
|
|
|
|
|
L. Note that this value should usually be a little larger than the maximum |
268
|
|
|
|
|
|
|
amount of time you expect any one request to take. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 heartbeat_interval |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
heartbeat_interval => 3 |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Heartbeat interval in seconds, defaults to the value of L. |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=head2 heartbeat_timeout |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
heartbeat_timeout => 2 |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
Maximum amount of time in seconds before a worker without a heartbeat will be stopped gracefully, defaults to the value |
281
|
|
|
|
|
|
|
of L. Note that this value should usually be a little larger than the |
282
|
|
|
|
|
|
|
maximum amount of time you expect any one operation to block the event loop. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head2 inactivity_timeout |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
inactivity_timeout => 10 |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
Maximum amount of time in seconds a connection with an active request can be inactive before getting closed, defaults |
289
|
|
|
|
|
|
|
to the value of L. Setting the value to C<0> will allow connections to be |
290
|
|
|
|
|
|
|
inactive indefinitely. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head2 keep_alive_timeout |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
keep_alive_timeout => 10 |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
Maximum amount of time in seconds a connection without an active request can be inactive before getting closed, |
297
|
|
|
|
|
|
|
defaults to the value of L. Setting the value to C<0> will allow connections |
298
|
|
|
|
|
|
|
to be inactive indefinitely. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head2 listen |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
listen => ['http://*:80'] |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Array reference with one or more locations to listen on, defaults to C. See also |
305
|
|
|
|
|
|
|
L for more examples. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=head2 pid_file |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
pid_file => '/var/run/hypnotoad.pid' |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
Full path to process id file, defaults to C in the same directory as the application. Note that this |
312
|
|
|
|
|
|
|
value can only be changed after the server has been stopped. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head2 proxy |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
proxy => 1 |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Activate reverse proxy support, which allows for the C and C headers to be picked |
319
|
|
|
|
|
|
|
up automatically, defaults to the value of L. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head2 requests |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
requests => 50 |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Number of keep-alive requests per connection, defaults to the value of L. |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=head2 spare |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
spare => 4 |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
Temporarily spawn up to this number of additional workers if there is a need, defaults to the value of |
332
|
|
|
|
|
|
|
L. This allows for new workers to be started while old ones are still shutting down |
333
|
|
|
|
|
|
|
gracefully, drastically reducing the performance cost of worker restarts. |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head2 trusted_proxies |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
trusted_proxies => ['10.0.0.0/8', '127.0.0.1', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'] |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
Trusted reverse proxies, addresses or networks in CIDR form. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=head2 upgrade_timeout |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
upgrade_timeout => 45 |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
Maximum amount of time in seconds a zero downtime software upgrade may take before getting canceled, defaults to |
346
|
|
|
|
|
|
|
C<180>. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=head2 workers |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
workers => 10 |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Number of worker processes, defaults to the value of L. A good rule of thumb is two |
353
|
|
|
|
|
|
|
worker processes per CPU core for applications that perform mostly non-blocking operations, blocking operations often |
354
|
|
|
|
|
|
|
require more and benefit from decreasing concurrency with L"clients"> (often as low as C<1>). Note that during zero |
355
|
|
|
|
|
|
|
downtime software upgrades there will be twice as many workers active for a short amount of time. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
L implements the following attributes. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=head2 prefork |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
my $prefork = $hypnotoad->prefork; |
364
|
|
|
|
|
|
|
$hypnotoad = $hypnotoad->prefork(Mojo::Server::Prefork->new); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
L object this server manages. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=head2 upgrade_timeout |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
my $timeout = $hypnotoad->upgrade_timeout; |
371
|
|
|
|
|
|
|
$hypnotoad = $hypnotoad->upgrade_timeout(15); |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Maximum amount of time in seconds a zero downtime software upgrade may take before getting canceled, defaults to |
374
|
|
|
|
|
|
|
C<180>. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 METHODS |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
L inherits all methods from L and implements the following new ones. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head2 configure |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
$hypnotoad->configure('hypnotoad'); |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
Configure server from application settings. |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=head2 run |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
$hypnotoad->run('script/my_app'); |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
Run server for application and wait for L"MANAGER SIGNALS">. |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=head1 SEE ALSO |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
L, L, L. |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=cut |