Sarze - An HTTP server
XXX
Sarze is an HTTP server in Perl for AnyEvent-aware applications providing Promise-based API.
The Sarze
module has the server class.
There are following methods:
- $p = Sarze->run (...)
-
Run the server and return a promise that is resolved when the server is stopped.
XXX
- $p = Sarze->start (...)
-
Run the server and return a promise that is resolved with the server object when the server is ready to accept connections.
XXX
$p = $server->stop
Schedule the server to stop and return a promise that is resolved when the server is stopped.
XXX
$p = $server->completed
XXX Promise must be resolved with an object that is XXX
Following options can be specified to start
and run
methods:
- hostports => [[$host, $port], ...] (required)
-
An array reference of zero or more host/port pair array references. A host/port pair must be either a pair of IP address and port (for TCP socket) or a pair of string
unix/
and path to the file (for UNIX domain socket). - psgi_file_name
-
XXX
If the PSGI script file
psgi_file_name
is not found, or does not return a code reference, the promise returned by thestart
orrun
method is to be rejected with an error.If this option is specified, the
eval
option must not be specified. - eval
-
XXX
If the code throws, or if the code does not define the
&main::psgi_app
, the promise returned by thestart
orrun
method is to be rejected with an error.If this option is specified, the
psgi_file_name
option must not be specified. - [DEPRECATED] worker_background_class => $class
-
Specify the Perl class package name of the worker background class. If omitted, no worker background class is used. See "WORKER BACKGROUND CLASS".
Use of this option is deprecated.
- worker_state_class => $class,
-
Specify the Perl class package name of the worker state class. If omitted, no worker state class is used. See "WORKER STATE CLASS".
- worker_state_params => $value
-
Specify a
worker_state_class
dependent value, typically a hash reference representing parameters. If omitted, defaulted toundef
. A copy of this value is accessible from the worker state class'sstart
method. See "WORKER STATE CLASS". As a clone of the value is transferred to forked worker processes, it must not contain any blessed object. - max_worker_count => $non_negative_integer (Default: 3)
-
Specify the number of the concurrent HTTP worker processes.
- max_counts => {custom => $non_negative_integer} (Default: 0)
-
Specify the number of the concurrent custom worker processes.
- connections_per_worker
-
XXX
- seconds_per_worker => $seconds (default: 60*10)
-
After the seconds specified by this option has elapsed, a worker is switched to the shutdowning mode, where no incoming request is accepted anymore and any running handlers are expected to be stopped as far as possible.
- shutdown_timeout => $seconds (default: 60*1)
-
After the seconds specified by this option has elapsed from it was switched to the shutdowning mode, a worker is uncleanly terminated even when there is a running handler.
Sarze is a preforking HTTP server. It creates worker processes which handle coming HTTP connections.
Sarze first loads the server code, as specified by eval
or psgi_file_name
option, and then forks that as workers. This means that any variable value initialized at loading is shared among the workers executed by a server. For example,
## Bad example!
eval => q{
my $number = rand; ## This line is executed only once.
return sub {
return [200, [], [$number]];
};
},
... always returns the same number.
A server instance consist of multiple worker processes. There are two types of workers:
HTTP worker - An HTTP worker is expected to handle incoming HTTP
connections. It can also handle any other application-specific jobs
coming from application-dependent sources.
Custom worker - A custom worker is expected to handle any
application-specific jobs coming from application-dependent sources.
The worker state class of an application that enables custom workers
must implement the C<custom> method.
When a worker process is created, the worker state class, as specified by the worker_state_class
, is instantiated.
The class, if any, must be loaded as part of the server. That is, the code specified by the eval
or psgi_file_name
option must define the class either directly or by require
ing or use
ing other module.
The class must have the start
method. It is invoked when a worker process is created, before accepting connections. The method is invoked with arguments, given as following key/value pairs:
- params => $value
-
The value specified by the
worker_state_params
option. - signal => $signal
-
An AbortSignal object. The signal is aborted when the worker process is shutting down.
- state => $worker_state
-
The worker process state object of the worker process. See "WORKER PROCESS STATE OBJECT".
The start
method must return an array reference of two items: a worker state class dependent value and a promise (e.g. Promise). The method can instead return a promise, which is to be resolved with an array reference.
As no connection is handled before the start
method is returned (and the returned promise is resolved), the method can be used to run an application-dependent per-worker initialization steps.
If the start
method throws or the returned promise is rejected, the worker process is terminated immediately.
The first (index 0) item of the array reference returned by the start
method is set to the data
method's value of the worker process state object, such that it is accessible from PSGI application invocations.
The signal
is signaled just before the worker is shutting down, after the completion of handling of all requests. This can be used to run an application-dependent per-worker cleanup steps.
The second (index 1) item of the array reference returned by the start
method must be resolved when the application is ready to shutdown the worker process. The worker process delays the termination until the promise is resolved. Note that the promise can be resolved even before the signal
's invocation in case there is no additional cleanup steps.
The start
method is invoked before accepting any HTTP connections or invoking the custom
method.
The custom
method is expect to run an application-dependent custom worker steps. It is invoked only once when a custom worker process is ready. It is invoked with an argument: The worker process state object of the worker process (See "WORKER PROCESS STATE OBJECT"). The method may or may not return a promise. If it returns a promise, it may resolve the promise at any time. It should not throw. If it returns a promise, it should not be rejected. Note that when the method returns (or the promise is resolved) is irrelevant to the lifecycle of the custom worker process.
- WORKER PROCESS STATE OBJECT
-
A worker process has a single worker process state object. The
start
method of a worker state class is invoked withstate
option. A PSGI application is invoked withmanakai.server.state
in the PSGI environment (see manakai PSGI extensions specification <https://wiki.suikawiki.org/n/manakai%20PSGI%20extensions> for details). The application can access to per worker process states and can control the worker process through this object. It has following methods:- $value = $state->data
-
An application-specific value in the array reference returned by the
start
method of the worker state class, defaulted toundef
. Though the value cannot be changed, by using a hash reference as the value, it can hold application specific states which can be get or set by the PSGI application. - $state->abort ($reason?)
-
Ask the worker process to terminate. The worker process then stops as soon as possible. If a non-
undef
argument is specified, it is the "reason" exception object of abortion.This method should only be used in an exceptional situation, e.g. when the worker state class has detected a non-recoverable error.
- $state->features->{http}
-
Returns whether it is an HTTP worker or not. Note that this flag is not initialized when the
start
method is invoked. - $state->features->{custom}
-
Returns whether it is a custom worker or not. Note that this flag is not initialized when the
start
method is invoked.
DEPRECATED. When a worker state class is specified, the worker background class cannot be used.
When a worker process is created, the worker background class, as specified by the worker_background_class
option, is instantiated.
The class, if any, must be loaded as part of the server. That is, the code specified by the eval
or psgi_file_name
option must define the class.
The class must have the start
method. It is invoked when a worker process is created. It must return an object, which is referred to as worker background object. It may instead return a promise (e.g. Promise) object, which must be resolved with an object.
The start
method can be used to run any per-worker initialization steps. The worker will not accept any connection until the method returns an object (directly or indirectly through a promise). The method can also used to dispatch "background" steps running concurrently with HTTP connection processing.
A worker background object must have a stop
method, which is invoked when the worker process is expected to be terminated. If there is any "background" steps, it should be terminated as soon as possible. This method might be invoked even when there are ongoing HTTP connections.
A worker background object must have a completed
method, which must return a promise object. The promise must not be resolved until the worker background object is ready to be discarded. After the promise is resolved and all HTTP connections have been closed, the worker process exits. This can also be used by the worker background object to ask the worker to not accept incoming connections anymore.
A worker background object may have a destory
method, which is invoked after all HTTP connections have been closed and the "background" steps have stopped and just before the termination of the worker process. This method can be used to run the shutdown steps for the worker process. It can return a promise object, which will delay the termination of the worker process until the resolution.
A worker background object may have any other application specific methods.
The worker background object of the worker process can be obtained from a PSGI application by invoking the background
method of the manakai.server.state
object (see manakai PSGI extensions specification <https://wiki.suikawiki.org/n/manakai%20PSGI%20extensions> for details) of the PSGI environment. If there is no worker background object, the background
method returns undef
.
While the Sarze server is running, it receives signals.
When it receives one of SIGINT
, SIGTERM
, or SIGQUIT
, it stops (as if the stop
method were invoked).
It might not immediately terminate the server when it is still in the process of generating and sending a response. Once it receives a signal, it uninstalls the signal handler. By sending the second signal, which is processed by Perl's default handler, the entire application exits and Sarze's graceful termination process is aborted.
The Sarze
module requires Perl 5.12 or later.
It requires modules AnyEvnet::Socket and AnyEvent::Fork.
It also requires following Perl modules (submodules of this Git repository): <https://github.com/wakaba/perl-promise> (which has Promise, AbortController, and AbortSignal), <https://github.com/manakai/perl-streams>, <https://github.com/manakai/perl-web-datetime>, <https://github.com/manakai/perl-web-encodings>, <https://github.com/manakai/perl-web-resource>, and <https://github.com/manakai/perl-web-url>.
This module is available as a Git repository at <https://github.com/manakai/sarze>. It was transferred to the manakai project from <https://github.com/wakaba/sarze> on 26 April 2022.
Wakaba <[email protected]>.
Copyright 2016-2022 Wakaba <[email protected]>.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Hey! The above document had some coding errors, which are explained below:
- Around line 240:
-
'=item' outside of any '=over'
- Around line 282:
-
You forgot a '=back' before '=head1'