NAME

Proc::Topus - Spawn worker processes with IPC built-in

SYNOPSIS

use strict;
use warnings;

use Proc::Topus qw( spawn );

my $type = spawn({
  main    => sub {
    my ( $pairs ) = @_;

    for my $key ( keys %$pairs ) {
      for my $pair (@{ $pairs->{$key} }) {
        my $fh = $pair->{reader};

        my $in = <$fh>;
        chomp $in;

        print "Received '$in' from worker '$key'\n";
      }
    }

    for my $key ( keys %$pairs ) {
      for my $pair (@{ $pairs->{$key} }) {
        my $fh = $pair->{writer};

        print {$fh} "Hello, worker ($key)\n";
      }
    }

    return 'master';
  },

  conduit => 'pipe',

  workers => {
    foo => {
      count   => 2,
      conduit => 'socketpair',
      loader  => sub { print "In loader (foo)\n" },
      main    => sub { work( foo => @_ ) },
    },

    bar => {
      count   => 2,
      conduit => 'socketpair',
      loader  => sub { print "In loader (bar)\n" },
      main    => sub { work( bar => @_ ) },
    },
  },
});

print "Exiting from $type\n";


sub work {
  my ( $type, $reader, $writer ) = @_;

  print {$writer} "Hello, master\n";

  my $in = <$reader>;
  chomp $in;

  print "Received '$in' from master\n";

  return "worker ($type)";
}

DESCRIPTION

Proc::Topus spawns one or more worker processes from one or more worker groups. Each worker process is pre-allocated a pair of filehandles for communicating with the initial master process. An intermediate loader process is also created in order to take advantage of copy-on-write mechanisms, if present.

Workers are arranged in groups so that multiple different types of worker processes may be spawned at the same time. Each group of workers can be configured independently of the others to allow for maximum flexibility. This includes configuring the number of workers, the method in which the IPC filehandles are created and whether or not autoflush is enabled. These options may also be set globally for all groups.

A double-fork method is used to spawn individual worker processes. Initially a process is forked from the master process for each worker group. This intermediate process is used for loading worker-specific modules or performing other tasks specific to the worker group. Once the loading operations have completed, a configured number of worker processes are forked and the loader process exits.

EXPORTS

spawn( %args )

spawn( \%args )

The spawn() function is the only thing exported from this module. It is responsible for performing all of the forking operations. %args may contain the following options:

main => sub { ... }

This option specifies a sub-routine that will be run in the master process once all loaders have completed. It is passed a single HASH reference containing all of the IPC filehandles. The structure is similar to the following:

{
  $name => [
    { reader => $rh, writer => $wh },
    ...
  ],
  ...
}

The return value from this sub-routine is used as the return from spawn() in the master process. This is intended to allow for returning an application-specific data structure.

If this option is not present the same structure that would normally be passed to the call-back is returned from spawn().

conduit => $conduit

This option specifices the default way the IPC filehandles are created for all worker groups. This can either be 'socketpair' or 'pipe'. If not present it defaults to 'socketpair'.

autoflush => $autoflush

This options is a boolean value for controlling the default autoflush behavior for the IPC filehandles for all worker groups. When true, autoflush is turned on. When false, autoflush is turned off. If not present it defaults to true.

workers => { $name => \%config, ... }

This option specifies the configuration for the worker processes. This option is required. Workers are grouped by $name and each have their own configuration. %config may contain the following options:

count => $count

This option specifies the number of worker processes that will be spawned. It is required.

loader => sub { ... }

This option specifies a sub-routine that is used as a call-back during the loading phase. This allows resources to be loaded before individual worker processes are forked. This can be used to take advantage of copy-on-write features or to allocate resources that should be shared amongst each worker process.

setsid => $setsid

This option is a boolean value for controlling whether or not POSIX::setsid() is called during the loading phase. If not specified, setsid() will not be called.

conduit => $conduit

This option specifies the way the IPC filehandles are created for the worker group. This can either be 'socketpair' or 'pipe'. If not present, the global value will be used. If no global value is specified it defaults to 'socketpair'.

autoflush => $autoflush

This option is a boolean value for controlling the autoflush behavior for the IPC filehandles for the worker group. When true, autoflush is turned on. When false, autoflush is turned off. If not present, the global value will be used. If no global value is specified it defaults to true.

main => sub { ... }

This option specifies a sub-routine that will be run in the worker process once it has been forked. It is passed two parameters: the read filehandle and the write filehandle. The return value from this sub-routine is used as the return from spawn() in the worker process.

If this option is not present the same filehandles are returned from spawn() as an ARRAY reference with the read filehandle located at index 0 and the write filehandle located at index 1.

AUTHOR

jason hord <pravus@cpan.org>

COPYRIGHT

Copyright (c) 2012-2014, jason hord

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.