The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

IOMux - simplify use of file-event loops

INHERITANCE

 IOMux is extended by
   IOMux::Poll
   IOMux::Select

SYNOPSIS

  use IOMux;
  use IOMux::Service::TCP;

  my $mux    = IOMux->new;
  my $server = IOMux::Service::TCP->new(...);
  $mux->add($server);
  $mux->loop;
  exit 0;

DESCRIPTION

IOMux is designed to take the effort out of managing multiple socket, file or pipe connections within a single process. It is essentially a really fancy front end to various kinds of event mechanisms, currently limited to select and poll.

In addition to maintaining the event loop, all input and output of the data stream gets buffered for you which tends to be quite difficult in event driven programs. Methods are provided to simulate common methods for IO::Handle

On many platforms, the capabilities of various event mechanisms differ a lot. Be careful which mechanism you pick. Test it! Read the man-pages which contain information about limitations and please contribute information you discover.

See "DETAILS" far below for a long description about

  • event managers select() and poll()

  • managed file handles

  • interesting implementation details.

There are at least ten other event modules on CPAN. See IOMux::Alternatives for a comparison between this module and, amongst other, IO::Multiplex, AnyEvent, IO::Async and <POE>.

METHODS

Constructors

IOMux->new(OPTIONS)

There can only be one of these objects in your program. After instantiating this, you will add() file-handles and sockets. Finally, loop() is called to go into select-driven connection handling.

There are currently no OPTIONS, but they will probably arrive in the upcoming releases.

Accessors

User interface

$obj->add(HANDLER|BUNDLE)

Add an HANDLER or BUNDLE to the multiplexer. Handlers extend IOMux::Handler. Bundles are related sets of handlers and extend IOMux::Bundle.

$obj->endLoop(BOOLEAN)

When this flag is set to true, the activities will end after having processed all currently flagged handles. All open handles when get closed cleanly.

The loop will also be terminated when all the handlers are removed (closed) That is a saver way to close the activities of your program where a call to endLoop() in many uses can be seen as tricky side-effect of a single handler.

$obj->loop( [HEARTBEAT] )

Enter the main loop and start processing IO events. The loop will terminate when all handles are closed, serious errors emerge or endLoop() was called.

You may provide a HEARTBEAT code reference, which will get called each time the internal select() has found a file handle with something to do or a timeout has expired. As arguments, it get the multiplexer object, the number of events and the time left to the next timeout. The validity of that third argument depends on the operating system and the actual muxer type.

example: loop

  $mux->loop;
  exit 0;

example: loop with heartbeat

  sub hb($$)
  {   my ($mux, $count, $t) = @_;
      ...
  }

  $mux->loop(\&hb);
$obj->open(MODE, PARAMS)

This open() provides a simplified interface to IOMux::Open, which on its turn is a simplification on using all kinds of handlers. See the manual of IOMux::Open for an extended description of the use.

example:

  use IOMux::Open '-|';  # loads handler code
  sub print_line($$)
  {   my ($handler, $line) = @_;
      print "line = $line";
  }

  # the short form
  my $who = $mux->open('-|', 'who');
  $who->readline(\&print_line);

  # equivalent to the longer
  my $who = IOMux::Open->new('-|', 'who');
  $mux->add($who);
  $who->readline(\&print_line);

  # or even longer
  use IOMux::Pipe::Read;
  my $who = IOMux::Pipe::Read->new(command => 'who');
  $mux->add($who);
  $who->readline(\&print_line);

For internal use

The following methods are provided, but end-users should avoid calling these methods directly: call them via the specific extension of IOMux::Handler.

$obj->changeTimeout(FILENO, OLDTIMEOUT, NEWTIMEOUT)

One of the connections wants to change its timeouts. A value of zero or undef means not active.

The correct OLDTIMEOUT must be provided to make it fast to detect whether this was the first timeout to expire. Checking the first timeout takes O(n) time, so we wish to avoid that.

example:

  # set timeout
  $mux->changeTimeout($conn->fileno, undef, 10);

  # better this way
  $conn->timeout(10);
$obj->fdset(FILENO, STATE, READ, WRITE, EXCEPT)

Change the select bit STATE for the FILENO. Change the READ, WRITE and/or EXCEPTion state. End-users should never need this.

example:

  # clear read and except, keep write
  $mux->fdset($conn->fileno, 0, 1, 0, 1);

  # better this way:
  $conn->fdset(0, 1, 0, 1);
$obj->handler( FILENO, [HANDLER] )

Returns (or sets) the handler which maintains FILENO.

example:

  $mux->handler(1);   # probably STDOUT
$obj->handlers()

Returns a list of all registered handlers (also the listening sockets).

example:

  foreach my $handler ($mux->handlers)
  {   say $handler->name;
  }
$obj->remove(FILENO)

Remove a connection from the multiplexer. Better to use the connection close method.

example:

  $mux->remove($conn->fileno);

  # better this way:
  $conn->close;

DETAILS

Installation

Many components of IO-driven programming are quite platform dependent. Therefore, IOMux does not enforce the installation of these dependencies during installation. However, when you choose to use some of the components, you will discover you need to install additional modules. For instance, when you use IOMux::Poll you will need IO::Poll.

Many perl modules (like LWP) use autoloading to get additional code in when it gets used. This is a nice help for users who do not need to load those modules explicitly. It is also a speed-up for the boot-time of scripts. However, IOMux is usually run in a daemon (see examples/ directory) which should load all code before child processes are started. Besides, initialization time does not really matter for daemons.

Event managers

The following event managers are available on the moment:

  • IOMux::Select

    uses a select call (see "man 2 select" on UNIX/Linux). The number of file handles it can monitor is limited (but quite large) and the overhead increases with the number of handles. On Windows only usable with sockets, no pipes nor files.

  • IOMux::Poll

    uses a poll call (see "man 2 poll" on UNIX/Linux). Not available on Windows, afaik. More efficient than select when the number of file handles grows, and many more filehandles can be monitored at once.

Other possible mechanisms include epoll, ppoll, pselect, kqueue, and Glib, may get added later. Connections to other event frameworks as POE, IO::Async, and AnyEvent may get added as well.

File handles

The event managers looks to one or more file handles for changes: either the write buffer gets empty (the program may send more), requested data has arrived (ready to be read) or (unexpected) error text comes in.

The following handles are supported, although maybe not on your platform.

SEE ALSO

This module is part of IOMux distribution version 0.13, built on July 21, 2015. Website: http://perl.overmeer.net/ All modules in this suite: "Any::Daemon", "IOMux", and "IOMux::HTTP".

Please post questions or ideas to perl@overmeer.net

LICENSE

Copyrights 2011-2015 by [Mark Overmeer]. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html