=head1 NAME AnyEvent::MP::Base - basis for AnyEvent::MP and Coro::MP =head1 SYNOPSIS # use AnyEvent::MP or Coro::MP instead =head1 DESCRIPTION This module provides most of the basic functionality of AnyEvent::MP, exposed through higher level interfaces such as L and L. =head1 GLOBALS =over 4 =cut package AnyEvent::MP::Base; use common::sense; use Carp (); use MIME::Base64 (); use AE (); use AnyEvent::MP::Node; use AnyEvent::MP::Transport; use base "Exporter"; our $VERSION = '0.01'; our @EXPORT = qw( NODE $NODE snd del _any_ become_slave become_public ); our $DEFAULT_SECRET; our $CONNECT_INTERVAL = 5; # new connect every 5s, at least our $CONNECT_TIMEOUT = 30; # includes handshake =item $AnyEvent::MP::Base::WARN This value is called with an error or warning message, when e.g. a connection could not be created, authorisation failed and so on. The default simply logs the message to STDERR. =cut our $WARN = sub { warn "$_[0]\n"; }; sub nonce($) { my $nonce; if (open my $fh, "send ([$port, @_]); } sub del($) { my ($noderef, $port) = split /#/, shift, 2; delete $PORT{$port}; my $mon = delete $LMON{$port} or return; $_->() for values %$mon; } sub become_public { return if $PUBLIC; my $noderef = join ",", @_; my @args = @_; $NODE = (AnyEvent::MP::Node::normalise_noderef $noderef)->recv; for my $t (split /,/, $NODE) { $NODE{$t} = $NODE{""}; my ($host, $port) = AnyEvent::Socket::parse_hostport $t; $LISTENER{$t} = AnyEvent::MP::Transport::mp_server $host, $port, @args, sub { my ($tp) = @_; # TODO: urgs my $node = add_node $tp->{remote_node}; $node->{trial}{accept} = $tp; }, ; } $PUBLIC = 1; } ############################################################################# # self node code our %node_req = ( # monitoring mon0 => sub { # disable monitoring my $portid = shift; my $node = $SRCNODE; $NODE{""}->unmonitor ($portid, delete $node->{rmon}{$portid}); }, mon1 => sub { # enable monitoring my $portid = shift; my $node = $SRCNODE; $NODE{""}->monitor ($portid, $node->{rmon}{$portid} = sub { $node->send (["", exit => $portid]); }); }, exit => sub { my $cbs = delete $SRCNODE->{lmon}{$_[0]} or return; $_->() for @$cbs; }, # well-known-port lookup wkp => sub { my $wkname = shift; snd @_, $WKP{$wkname}; }, # relay message to another node / generic echo relay => sub { &snd; }, # random garbage eval => sub { my @res = eval shift; snd @_, "$@", @res if @_; }, time => sub { snd @_, AE::time; }, devnull => sub { # }, ); $NODE{""} = new AnyEvent::MP::Node::Self noderef => $NODE; $PORT{""} = sub { &{ $node_req{+shift} or return } }; =back =head1 SEE ALSO L. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ =cut 1