DESCRIPTION POE::Class::Server::PreFork - Class for preforking and monitoring server sessions. SYNOPSIS use POE qw(Class::Server::PreFork); my $server = new POE::Class::Server::PreFork::Something; my $preforked = new POE::Class::Server::PreFork( server => $server, # optional and default shutdown_on_error => 1, min_spare_servers => 1, max_spare_servers => 2, start_servers => 5, max_clients => 50, timeout => 0, ); printf "Created prefork server with ID %d\n", $preforker->ID; # Create the session my $session = $preforked->start; printf "Created prefork session with ID %d\n", $session->ID; # don't forget this $poe_kernel->run; DESCRIPTION POE::Class::Server::PreFork is more or less a monitor. It tracks forked sessions, reforkes them when they timeout and preforks them to the given specifications. POE::Class::Server::PreFork isa POE::Class. ACCESSOR METHODS All accessors have three methods ala POE::Class::Attribs. set_ATTRIB, get_ATTRIB and ATTRIB. Set and get are obvious. ATTRIB is simply a set/get method. See POE::Class::Attribs for more details. server This is the object used for the server session. POE::Class::Server::PreFork comes with two such classes. POE::Class::Server::PreFork::TCP and POE::Class::Server::PreFork::UNIX. shutdown_on_error shutdown_on_error says whether the server should yield shutdown if an error occurs with the child server. See POE::Wheel::Run for possible errors. min_spare_servers max_spare_servers These are the maximum and minimum spare (non-busy) servers PreFork should keep around. start_servers The number of servers PreFork should initially start with. This will be set to max_clients if it is greater than max_clients. max_clients This is the maximum number of child servers that will be launched. timeout This is the approximate time in seconds a child is allowed to block. INTERNALS This section is for people who wish to subclass POE::Class::Server::PreFork. If you are not such a person you may stop reading now. The Server Object The "server" object's session is started from within this class so that it becomes a child of this class. It is started with the method "start()" which is probably inherited from POE::Class. When it is started it is expected to setup a socket of some kind. It should NOT start accepting connections yet, that comes later. When PreFork initially starts it calles the child server's method send_ack with the proper interval PreFork needs ACKs for set_timeouts. After that, PreFork calles the child server's "start()" method. An ACK is the constant COMM_ACK, defined in this class, printed to STDOUT by the child server. PreFork forks child servers using POE::Wheel::Run. When PreFork forks it detaches the child session so that the session used by PreFork can exit. The child server's session object is accessed with the "get_session()" method (also inherited from POE::Class). Then PreFork posts a "resume_accept" event to the child server's session. This is the event that tells the child server session to start accepting connections now. In addition to ACKs the server child is responsible for letting us know when it is busy and when it is free. It does this by printing the COMM_BUSY or COMM_NOT_BUSY constants, defined in this package, to STDOUT. This constants COMM_BUSY, COMM_NOT_BUSY and COMM_ACK can be exported from this class use POE::Class::Server::PreFork qw(COMM_BUSY COMM_NOT_BUSY COMM_ACK); # -or- use POE::Class::Server::PreFork qw(:all); Server Tracking Child Servers are tracked using three hash references which can be accessed by methods: busy_servers free_servers These methods store a hash that maps the PID of the child process to a hash containing wheel The POE::Wheel::Run object used to fork off the child. See POE::Wheel::Run for details on methods. last_ack The last time PreFork recieved an ACK. This is used to timeout the process. It is unix time returned by time(). starttime This stores the time() this process started. PreFork uses this time to decide which process to kill off when it is going back down to "max_spare_servers". PreFork kill the oldest non-busy server. Both of these combined are all the child servers. wheel_id_to_pid This hash simply maps POE::Wheel::Run ID to PID. It is needed in places PreFork only has the Wheel ID. Handlers These are the handlers this session defines. Handlers are all object states defined in the method "create_states()" which is called from the base class POE::Class. The following show the name of the state on the left and the name of the method on the right. _start => handler_start This handler is called when the PreFork session starts. It does some normalization on the attributes that are not set and or set to things that do not make sense. PreFork then creates the server child session and yields to forkoff. _child => handler_child Used to know if the server child session has ended for some reason (possibly an error). If it has ended PreFork yields shutdown. _stop => handler_stop Used to cleanup internal data structures. run_error => handler_run_error "handler_run_error()" is called by POE::Wheel::Run when an error occurs with the processes PeFork forked. See the StderrEvent in POE::Wheel::Run for details on arguments. This handler warns the error and yields shutdown if "shutdown_on_error()" is true. shutdown => handler_shutdown Puts us in the shutdown state and removes all alarms. In the forked child deletes all internal references to wheels so the PreFork session ends. In the parent it sends a SIGINT to all of the children. server_closed => handler_server_closed Called by POE::Wheel::Run when a child closes all it's output channels (PreFork assumes this means it exited). See the CloseEvent in POE::Wheel::Run for details on arguments. PreFork uses this handler to remove tracked POE::Wheel::Run wheels and to yield forkoff unless it is in a "Shutdown()" state. server_stderr => handler_server_stderr Called from POE::Wheel::Run when a child produces STDERR. See POE::Wheel::Run for details on this handler's arguments. This handler looks up the child hash and calles the "server_stderr()" method with the child's hash reference as the first argument and the input as the second. server_ack => handler_server_ack StdoutEvent from POE::Wheel::Run. If the output is the constant COMM_ACK calles the method "server_ack()", if the output is the constant COMM_BUSY calles the method "server_busy()", if the output is the constant COMM_NOT_BUSY calles the method "server_not_busy()" else calles the method "server_stdout()". server_timeout_check => handler_server_timeout_check Called on a timer of "get_timeout()" * 1.5. Checks all children to see that they have sent an ACK within "get_timeout()" seconds. If a free server is timeing out calles the method "server_timeout_free()", if a busy server is timeing out calles "server_timeout_busy()". If any servers have timed out yield forkoff. forkoff => handler_forkoff This handler is the main code for handling child server monitoring. It kills off the oldest processes if PreFork is over "get_max_spare_servers()", starts the initial "get_start_servers()" if total servers is zero, or yields server_fork for every child server PreFork is under "get_min_spare_servers()". server_fork => handler_server_fork Uses POE::Wheel::Run to fork of a child process. Calles the method "server_start()" from within the child process. Stores the child hash in "free_servers()" and the wheel ID to PID in "wheel_id_to_pid()". Methods Many of these methods were created to provide a simpler subclass interface. create_states Creates the following states run_error => handler_run_error server_closed => handler_server_closed server_stderr => handler_server_stderr server_ack => handler_server_ack server_timeout_check => handler_server_timeout_check server_fork => handler_server_fork forkoff => handler_forkoff See "Handlers" for details. server_timeout This method is called when a server has timed out. It sends a SIGINT to the process. server_timeout_busy server_timeout_free Server objects send information back to the monitor via STDOUT. This information lets the monitor know if the server is busy or not. "server_timeout_busy()" or "server_timeout_free()" are called when a free or busy server times out respectivly. The only argument to these methods is the child's hash. Both of these methods do the same thing by default (with slightly different debug information in debug mode). They call "server_timeout()" and removes the references to the childs wheel. server_start Called from within the forked process. Does the following: Detaches the child session. Pauses all wheels to keep them from getting input before they are destroyed. Posts a resume_accept event to the server child session, set. Calles the shutdown state. server_ack Takes the child hash reference as the first argument. Sets the last_ack attribute in the child hash to the current time. server_not_busy Takes the child hash reference as the first arugment. Moves the reference for this child from the "busy_servers()" hash to the "free_servers()" hash. server_busy Takes the child hash reference as the first arugment. Moves the reference for this child from the "free_servers()" hash to the "busy_servers()" hash. server_stdout Called when the child server produces stdout that is not recognized. Takes the child hash reference as the first argument and the output as the second. Prints the output to STDOUT prefixed with "$pid STDOUT: ". server_stderr Called when the child server produces stderr that is not recognized. Takes the child hash reference as the first argument and the output as the second. Prints the output to STDERR prefixed with "$pid STDERR: ". busy_servers Returns the hash reference of busy server childs. free_servers Returns the hash reference of non-busy server childs. wheel_id_to_pid Returns the hash reference that maps server childs wheel ID to PID. server_check_ack The interval we check for timed out children. is_child Used to know if we are the forked child. This is set in "server_start()". BUGS The documentation is not complete. Tests are far from complete. AUTHOR Scott Beck SEE ALSO POE POE::Class POE::Class::Server::PreFork::TCP POE::Class::Server::PreFork::UNIX