--- AnyEvent-FCP/FCP.pm 2016/06/07 18:53:23 1.19 +++ AnyEvent-FCP/FCP.pm 2016/06/15 09:21:14 1.26 @@ -63,7 +63,7 @@ use Carp; -our $VERSION = 0.4; +our $VERSION = 0.5; use Scalar::Util (); @@ -88,7 +88,7 @@ lc } -=item $fcp = new AnyEvent::FCP [host => $host][, port => $port][, name => $name] +=item $fcp = new AnyEvent::FCP key => value...; Create a new FCP connection to the given host and port (default 127.0.0.1:9481, or the environment variables C and C). @@ -96,6 +96,55 @@ If no C was specified, then AnyEvent::FCP will generate a (hopefully) unique client name for you. +The following keys can be specified (they are all optional): + +=over 4 + +=item name => $string + +A unique name to identify this client. If none is specified, a randomly +generated name will be used. + +=item host => $hostname + +The hostname or IP address of the freenet node. Default is C<$ENV{FREDHOST}> +or C<127.0.0.1>. + +=item port => $portnumber + +The port number of the FCP port. Default is C<$ENV{FREDPORT}> or C<9481>. + +=item timeout => $seconds + +The timeout, in seconds, after which a connection error is assumed when +there is no activity. Default is C<7200>, i.e. two hours. + +=item keepalive => $seconds + +The interval, in seconds, at which keepalive messages will be +sent. Default is C<540>, i.e. nine minutes. + +These keepalive messages are useful both to detect that a connection is +no longer working and to keep any (home) routers from expiring their +masquerading entry. + +=item on_eof => $callback->($fcp) + +Invoked when the underlying L signals EOF, currently +regardless of whether the EOF was expected or not. + +=item on_error => $callback->($fcp, $message) + +Invoked on any (fatal) errors, such as unexpected connection close. The +callback receives the FCP object and a textual error message. + +=item on_failure => $callback->($fcp, $type, $args, $backtrace, $error) + +Invoked when an FCP request fails that didn't have a failure callback. See +L for details. + +=back + =cut sub new { @@ -192,7 +241,13 @@ connect => [$self->{host} => $self->{port}], timeout => $self->{timeout}, on_read => $on_read, - on_eof => $self->{on_eof}, + on_eof => sub { + if ($self->{on_eof}) { + $self->{on_eof}($self); + } else { + $self->fatal ("EOF"); + } + }, on_error => sub { $self->fatal ($_[2]); }, @@ -216,7 +271,7 @@ delete $self->{kw}; if ($self->{on_error}) { - $self->{on_error}->($msg); + $self->{on_error}->($self, $msg); } else { die $msg; } @@ -372,7 +427,7 @@ $fcp->get_plugin_info_ ($name, $detailed, $cb); -You can thinbk of the underscore as a kind of continuation indicator - the +You can think of the underscore as a kind of continuation indicator - the normal function waits and returns with the data, the C<_> indicates that you pass the continuation yourself, and the continuation will be invoked with the results. @@ -384,11 +439,26 @@ =item A code reference (or rather anything not matching some other alternative) This code reference will be invoked with the result on success. On an -error, it will die (in the event loop) with a backtrace of the call site. +error, it will invoke the C callback of the FCP object, or, +if none was defined, will die (in the event loop) with a backtrace of the +call site. This is a popular choice, but it makes handling errors hard - make sure you never generate protocol errors! +In the failure case, if an C hook exists, it will be invoked +with the FCP object, the request type (the name of the method, an arrayref +containing the arguments from the original request invocation, a (textual) +backtrace as generated by C, and the error object from the +server, in this order, e.g.: + + on_failure => sub { + my ($fcp, $request_type, $orig_args, $backtrace, $error_object) = @_; + + warn "FCP failure ($type @$args), $error_object->{code_description} ($error_object->{extra_description})$backtrace"; + exit 1; + }, + =item A condvar (as returned by e.g. C<< AnyEvent->condvar >>) When a condvar is passed, it is sent (C<< $cv->send ($results) >>) the @@ -402,11 +472,14 @@ The C<$success> callback will be invoked with the results, while the C<$failure> callback will be invoked on any errors. +The C<$failure> callback will be invoked with the error object from the +server. + =item C This is the same thing as specifying C as callback, i.e. on -success, the results are ignored, while on failure, you the module dies -with a backtrace. +success, the results are ignored, while on failure, the C hook +is invoked or the module dies with a backtrace. This is good for quick scripts, or when you really aren't interested in the results. @@ -436,9 +509,15 @@ } elsif (UNIVERSAL::isa $ok, AnyEvent::CondVar::) { $err = sub { $ok->croak ($_[0]{extra_description}) }; } else { - my $bt = Carp::longmess ""; + my $bt = Carp::longmess "AnyEvent::FCP request $name"; + Scalar::Util::weaken (my $self = $_[0]); + my $args = [@_]; shift @$args; $err = sub { - die "$_[0]{code_description} ($_[0]{extra_description})$bt"; + if ($self->{on_failure}) { + $self->{on_failure}($self, $name, $args, $bt, $_[0]); + } else { + die "$_[0]{code_description} ($_[0]{extra_description})$bt"; + } }; } @@ -660,7 +739,7 @@ =item $status = $fcp->remove_request ($identifier[, $global]) -Remove the request with the given isdentifier. Returns true if successful, +Remove the request with the given identifier. Returns true if successful, false on error. =cut @@ -715,7 +794,7 @@ want to read (get) files or write (put) files, respectively. On error, an exception is thrown. Otherwise, C<$can_read> and -C<$can_write> indicate whether you can reaqd or write to freenet via the +C<$can_write> indicate whether you can read or write to freenet via the directory. =cut @@ -846,9 +925,9 @@ To fill this cache with the global queue and keep it updated, call C to subscribe to updates, followed by -C. +C. - $fcp->watch_global_sync_; # do not wait + $fcp->watch_global_; # do not wait $fcp->list_persistent_requests; # wait To get a better idea of what is stored in the cache, here is an example of @@ -967,7 +1046,7 @@ } # see if the dummy plugin is loaded, to ensure all previous requests have finished. - $fcp->get_plugin_info_sync ("dummy"); + $fcp->get_plugin_info ("dummy"); =head1 SEE ALSO