Skip to content

manakai/sarze

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

=head1 NAME

Sarze - An HTTP server

=head1 SYNOPSIS

XXX

=head1 DESCRIPTION

B<Sarze> is an HTTP server in Perl for L<AnyEvent>-aware applications
providing L<Promise>-based API.

The C<Sarze> module has the server class.

=head1 METHODS

There are following methods:

=over 4

=item $p = Sarze->run (...)

Run the server and return a promise that is resolved when the server
is stopped.

XXX

=item $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

=back

=head1 OPTIONS

Following options can be specified to C<start> and C<run> methods:

=over 4

=item 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 C<unix/> and path to the file (for UNIX
domain socket).

=item psgi_file_name

XXX

If the PSGI script file C<psgi_file_name> is not found, or does not
return a code reference, the promise returned by the C<start> or
C<run> method is to be rejected with an error.

If this option is specified, the C<eval> option must not be specified.

=item eval

XXX

If the code throws, or if the code does not define the
C<&main::psgi_app>, the promise returned by the C<start> or C<run>
method is to be rejected with an error.

If this option is specified, the C<psgi_file_name> option must not be
specified.

=item [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 L</WORKER
BACKGROUND CLASS>.

Use of this option is B<deprecated>.

=item worker_state_class => $class,

Specify the Perl class package name of the worker state class.  If
omitted, no worker state class is used.  See L</WORKER STATE CLASS>.

=item worker_state_params => $value

Specify a C<worker_state_class> dependent value, typically a hash
reference representing parameters.  If omitted, defaulted to C<undef>.
A copy of this value is accessible from the worker state class's
C<start> method.  See L</WORKER STATE CLASS>.  As a clone of the value
is transferred to forked worker processes, it must not contain any
blessed object.

=item max_worker_count => $non_negative_integer  (Default: 3)

Specify the number of the concurrent HTTP worker processes.

=item max_counts => {custom => $non_negative_integer}  (Default: 0)

Specify the number of the concurrent custom worker processes.

=item connections_per_worker

XXX

=item 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.

=item 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.

=back

=head1 SERVER APPLICATION

Sarze is a preforking HTTP server.  It creates worker processes which
handle coming HTTP connections.

Sarze first loads the server code, as specified by C<eval> or
C<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.

=head1 WORKERS

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.

=head1 WORKER STATE CLASS

When a worker process is created, the B<worker state class>, as
specified by the C<worker_state_class>, is instantiated.

The class, if any, must be loaded as part of the server.  That is, the
code specified by the C<eval> or C<psgi_file_name> option must define
the class either directly or by C<require>ing or C<use>ing other
module.

The class must have the B<C<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:

=over 4

=item params => $value

The value specified by the C<worker_state_params> option.

=item signal => $signal

An L<AbortSignal> object.  The signal is aborted when the worker
process is shutting down.

=item state => $worker_state

The worker process state object of the worker process.  See L</WORKER
PROCESS STATE OBJECT>.

=back

The C<start> method must return an array reference of two items: a
worker state class dependent value and a promise (e.g. L<Promise>).
The method can instead return a promise, which is to be resolved with
an array reference.

As no connection is handled before the C<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 C<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
C<start> method is set to the C<data> method's value of the worker
process state object, such that it is accessible from PSGI application
invocations.

The C<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
C<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 C<signal>'s invocation in case there is no
additional cleanup steps.

The C<start> method is invoked before accepting any HTTP connections
or invoking the C<custom> method.

The C<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 L</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.

=item WORKER PROCESS STATE OBJECT

A worker process has a single B<worker process state object>.  The
C<start> method of a worker state class is invoked with C<state>
option.  A PSGI application is invoked with C<manakai.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:

=over 4

=item $value = $state->data

An application-specific value in the array reference returned by the
C<start> method of the worker state class, defaulted to C<undef>.
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.

=item $state->abort ($reason?)

Ask the worker process to terminate.  The worker process then stops as
soon as possible.  If a non-C<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.

=item $state->features->{http}

Returns whether it is an HTTP worker or not.  Note that this flag is
not initialized when the C<start> method is invoked.

=item $state->features->{custom}

Returns whether it is a custom worker or not.  Note that this flag is
not initialized when the C<start> method is invoked.

=back

=head1 WORKER BACKGROUND CLASS

B<DEPRECATED>.  When a worker state class is specified, the worker
background class cannot be used.

When a worker process is created, the B<worker background class>, as
specified by the C<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 C<eval> or C<psgi_file_name> option must define
the class.

The class must have the B<C<start>> method.  It is invoked when a
worker process is created.  It must return an object, which is
referred to as B<worker background object>.  It may instead return a
promise (e.g. L<Promise>) object, which must be resolved with an
object.

The C<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 C<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 C<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 C<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 C<background> method of the
C<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 C<background> method returns C<undef>.

=head1 SIGNALS

While the Sarze server is running, it receives signals.

When it receives one of C<SIGINT>, C<SIGTERM>, or C<SIGQUIT>, it stops
(as if the C<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.

=head1 DEPENDENCY

The C<Sarze> module requires Perl 5.12 or later.

It requires modules L<AnyEvnet::Socket> and L<AnyEvent::Fork>.

It also requires following Perl modules (submodules of this Git
repository): <https://github.com/wakaba/perl-promise> (which has
L<Promise>, L<AbortController>, and L<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>.

=head1 HISTORY

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.

=head1 AUTHOR

Wakaba <wakaba@suikawiki.org>.

=head1 LICENSE

Copyright 2016-2022 Wakaba <wakaba@suikawiki.org>.

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut