--- AnyEvent-MP/MP.pm 2012/03/03 11:38:43 1.124 +++ AnyEvent-MP/MP.pm 2012/03/08 21:37:51 1.129 @@ -37,9 +37,9 @@ kil $port, my_error => "everything is broken"; # error kill # monitoring - mon $localport, $cb->(@msg) # callback is invoked on death - mon $localport, $otherport # kill otherport on abnormal death - mon $localport, $otherport, @msg # send message on death + mon $port, $cb->(@msg) # callback is invoked on death + mon $port, $localport # kill localport on abnormal death + mon $port, $localport, @msg # send message on death # temporarily execute code in port context peval $port, sub { die "kill the port!" }; @@ -199,6 +199,7 @@ snd rcv mon mon_guard kil psub peval spawn cal port db_set db_del db_reg + db_mon db_family db_keys db_values ); our $SELF; @@ -232,7 +233,7 @@ never) before calling other AnyEvent::MP functions. The key/value pairs are basically the same ones as documented for the -F command line utility (sans the set/del prefix), with two additions: +F command line utility (sans the set/del prefix), with these additions: =over 4 @@ -248,6 +249,14 @@ precedence over any values configured via the rc file. The default is for the rc file to override any options specified in the program. +=item secure => $pass->($nodeid) + +In addition to specifying a boolean, you can specify a code reference that +is called for every remote execution attempt - the execution request is +granted iff the callback returns a true value. + +See F for more info. + =back =over 4 @@ -273,10 +282,13 @@ If the profile specifies a node ID, then this will become the node ID of this process. If not, then the profile name will be used as node ID, with -a slash (C) attached. +a unique randoms tring (C) appended. -If the node ID (or profile name) ends with a slash (C), then a random -string is appended to make it unique. +The node ID can contain some C<%> sequences that are expanded: C<%n> +is expanded to the local nodename, C<%u> is replaced by a random +strign to make the node unique. For example, the F commandline +utility uses C as nodename, which might expand to +C. =item step 2, bind listener sockets @@ -303,10 +315,10 @@ configure -Example: become an anonymous node. This form is often used for commandline -clients. +Example: become a semi-anonymous node. This form is often used for +commandline clients. - configure nodeid => "anon/"; + configure nodeid => "myscript/%n/%u"; Example: configure a node using a profile called seed, which is suitable for a seed node as it binds on all local addresses on a fixed port (4040, @@ -825,6 +837,8 @@ }; } +#=item $cb2 = timeout $seconds, $cb[, @args] + =item cal $port, @msg, $callback[, $timeout] A simple form of RPC - sends a message to the given C<$port> with the @@ -889,37 +903,134 @@ contains values. The top level hash key is called "family", and the second-level hash key -is simply called "key". +is called "subkey" or simply "key". -The family and key must be alphanumeric ASCII strings, i.e. start -with a letter and consist of letters, digits, underscores and colons -(C<[A-Za-z][A-Za-z0-9_:]*>, pretty much like Perl module names. +The family must be alphanumeric, i.e. start with a letter and consist +of letters, digits, underscores and colons (C<[A-Za-z][A-Za-z0-9_:]*>, +pretty much like Perl module names. -As the family namespaceis global, it is recommended to prefix family names +As the family namespace is global, it is recommended to prefix family names with the name of the application or module using it. +The subkeys must be non-empty strings, with no further restrictions. + The values should preferably be strings, but other perl scalars should -work as well (such as arrays and hashes). +work as well (such as undef, arrays and hashes). -Every database entry is owned by one node - adding the same family/key +Every database entry is owned by one node - adding the same family/subkey combination on multiple nodes will not cause discomfort for AnyEvent::MP, but the result might be nondeterministic, i.e. the key might have different values on different nodes. -=item db_set $family => $key => $value +Different subkeys in the same family can be owned by different nodes +without problems, and in fact, this is the common method to create worker +pools. For example, a worker port for image scaling might do this: + + db_set my_image_scalers => $port; + +And clients looking for an image scaler will want to get the +C keys from time to time: + + db_keys my_image_scalers => sub { + @ports = @{ $_[0] }; + }; + +Or better yet, they want to monitor the database family, so they always +have a reasonable up-to-date copy: -Sets (or replaces) a key to the database. + db_mon my_image_scalers => sub { + @ports = keys %{ $_[0] }; + }; + +In general, you can set or delete single subkeys, but query and monitor +whole families only. + +If you feel the need to monitor or query a single subkey, try giving it +it's own family. + +=over + +=item db_set $family => $subkey [=> $value] -=item db_del $family => $key +Sets (or replaces) a key to the database - if C<$value> is omitted, +C is used instead. + +=item db_del $family => $subkey Deletes a key from the database. -=item $guard = db_reg $family => $key [=> $value] +=item $guard = db_reg $family => $subkey [=> $value] Sets the key on the database and returns a guard. When the guard is destroyed, the key is deleted from the database. If C<$value> is missing, then C is used. +=item db_family $family => $cb->(\%familyhash) + +Queries the named database C<$family> and call the callback with the +family represented as a hash. You can keep and freely modify the hash. + +=item db_keys $family => $cb->(\@keys) + +Same as C, except it only queries the family I and passes +them as array reference to the callback. + +=item db_values $family => $cb->(\@values) + +Same as C, except it only queries the family I and passes them +as array reference to the callback. + +=item $guard = db_mon $family => $cb->($familyhash, \@subkeys...) + +Creates a monitor on the given database family. Each time a key is set or +or is deleted the callback is called with a hash containing the database +family and an arrayref with subkeys that have changed. + +Specifically, if one of the passed subkeys exists in the $familyhash, then +it is currently set to the value in the $familyhash. Otherwise, it has +been deleted. + +The family hash reference belongs to AnyEvent::MP and B by the callback. When in doubt, make a copy. + +The first call will be with the current contents of the family and all +keys, as if they were just added. + +It is possible that the callback is called with a change event even though +the subkey is already present and the value has not changed. + +The monitoring stops when the guard object is destroyed. + +Example: on every change to the family "mygroup", print out all keys. + + my $guard = db_mon mygroup => sub { + my ($family, $keys) = @_; + print "mygroup members: ", (join " ", keys %$family), "\n"; + }; + +Exmaple: wait until the family "My::Module::workers" is non-empty. + + my $guard; $guard = db_mon My::Module::workers => sub { + my ($family, $keys) = @_; + return unless %$family; + undef $guard; + print "My::Module::workers now nonempty\n"; + }; + +Example: print all changes to the family "AnyRvent::Fantasy::Module". + + my $guard = db_mon AnyRvent::Fantasy::Module => sub { + my ($family, $keys) = @_; + + for (@$keys) { + print "$_: ", + (exists $family->{$_} + ? $family->{$_} + : "(deleted)"), + "\n"; + } + }; + =cut =back