IPC-MicroSocket

 view release on metacpan or  search on metacpan

lib/IPC/MicroSocket.pm  view on Meta::CPAN


   method on_request;

   method on_subscribe ( $topic );

   field %subscribed_topics;
   method is_subscribed ( $topic ) { return $subscribed_topics{ $topic }; }

   field $selector = Future::Selector->new;

   async method run ()
   {
      await $selector->run_until_ready( $self->_recv );
      return;
   }

   method on_recv ( $sigil, @args )
   {
      match( $sigil : eq ) {
         case( "(" ) {
            my $tag = shift @args;
            $selector->add(
               data => undef,
               f    => $self->on_request( @args )
                  ->then(
                     # done
                     sub ( @result ) { $self->send( ")", $tag, @result ) },
                     # fail
                     sub ( $err, @ ) { $self->send( "#", $tag, $err ) },
                  ),
               );
         }
         case( "+" ) {
            my $topic = shift @args;
            $subscribed_topics{ $topic } = 1;
            $self->on_subscribe( $topic );
         }

         default {
            warn "TODO: Unrecognised sigil $sigil\n";
         }
      }
   }

   method publish ( $topic, @args )
   {
      $selector->add(
         data => undef,
         f    => $self->send( "!", $topic, @args ),
      );
   }
}

=head1 FAQs

=head2 Why not ZeroMQ?

I found ZeroMQ to be a lot of effort to use from Perl, and most critically it
does not appear to support both request/response and publish/subscribe message
flows to share the same UNIX socket. To support that in ZeroMQ it would appear
to be necessary to create two separate endpoints, one for each kind of message
flow.

=head2 Why not JSON/YAML/your-favourite-serialisation?

I mostly built this for a few very-small use-cases involving simple byte
strings or plain ASCII text, for which the overhead of JSON, YAML, or other
kinds of serialisation would be unnecessary. As the presented message
semantics are just opaque byte buffers, you are free to layer on top whatever
kind of message serialisation you wish.

=head2 Why not IO::Async/Mojo/your-favourite-event-system?

I wanted to use this distribution as an exercise in writing "pure"
L<Future>-driven event logic, as an experiment to test out L<Future::Selector>
and other related design shapes.

=head1 TODO

There are a number of additional features that this module I<could> support.
Each will be considered if a use-case arises. Each would add extra code and
possible dependencies, and take away from the "micro" nature of the module, so
each would have to be considered on individual merit.

=over 4

=item *

Configurations for encoding and serialisation of arguments.

=item *

Unsubscribe from individual topics by request.

=item *

Helper methods for other socket types, such as TCP sockets.

=item *

Flexible matching of subscription topics; such as string prefixes or delimited
component paths.

=item *

Other kinds of message flows, such as server-buffered streams with atomic
catchup-and-subscribe semantics ensuring clients receive all the buffer.

=back

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>

=cut

0x55AA;



( run in 4.433 seconds using v1.01-cache-2.11-cpan-524268b4103 )