… | |
… | |
297 | $self->{id}{$kv->{identifier}}($self, $type, $kv, $rdata) |
297 | $self->{id}{$kv->{identifier}}($self, $type, $kv, $rdata) |
298 | and delete $self->{id}{$kv->{identifier}}; |
298 | and delete $self->{id}{$kv->{identifier}}; |
299 | } |
299 | } |
300 | } |
300 | } |
301 | |
301 | |
|
|
302 | =back |
|
|
303 | |
|
|
304 | =head2 FCP REQUESTS |
|
|
305 | |
|
|
306 | The following methods implement various requests. Most of them map |
|
|
307 | directory to the FCP message of the same name. The added benefit of |
|
|
308 | these over sending requests yourself is that they handle the necessary |
|
|
309 | serialisation, protocol quirks, and replies. |
|
|
310 | |
|
|
311 | All of them exist in two versions, the variant shown in this manpage, and |
|
|
312 | a variant with an extra C<_> at the end, and an extra C<$cb> argument. The |
|
|
313 | version as shown is I<synchronous> - it will wait for any replies, and |
|
|
314 | either return the reply, or croak with an error. The underscore variant |
|
|
315 | returns immediately and invokes one or more callbacks or condvars later. |
|
|
316 | |
|
|
317 | For example, the call |
|
|
318 | |
|
|
319 | $info = $fcp->get_plugin_info ($name, $detailed); |
|
|
320 | |
|
|
321 | Also comes in this underscore variant: |
|
|
322 | |
|
|
323 | $fcp->get_plugin_info_ ($name, $detailed, $cb); |
|
|
324 | |
|
|
325 | You can thinbk of the underscore as a kind of continuation indicator - the |
|
|
326 | normal function waits and returns with the data, the C<_> indicates that |
|
|
327 | you pass the continuation yourself, and the continuation will be invoked |
|
|
328 | with the results. |
|
|
329 | |
|
|
330 | This callback/continuation argument (C<$cb>) can come in three forms itself: |
|
|
331 | |
|
|
332 | =over 4 |
|
|
333 | |
|
|
334 | =item A code reference (or rather anything not matching some other alternative) |
|
|
335 | |
|
|
336 | This code reference will be invoked with the result on success. On an |
|
|
337 | error, it will die (in the event loop) with a backtrace of the call site. |
|
|
338 | |
|
|
339 | This is a popular choice, but it makes handling errors hard - make sure |
|
|
340 | you never generate protocol errors! |
|
|
341 | |
|
|
342 | =item A condvar (as returned by e.g. C<< AnyEvent->condvar >>) |
|
|
343 | |
|
|
344 | When a condvar is passed, it is sent (C<< $cv->send ($results) >>) the |
|
|
345 | results when the request has finished. Should an error occur, the error |
|
|
346 | will instead result in C<< $cv->croak ($error) >>. |
|
|
347 | |
|
|
348 | This is also a popular choice. |
|
|
349 | |
|
|
350 | =item An array with two callbacks C<[$success, $failure]> |
|
|
351 | |
|
|
352 | The C<$success> callback will be invoked with the results, while the |
|
|
353 | C<$failure> callback will be invoked on any errors. |
|
|
354 | |
|
|
355 | =item C<undef> |
|
|
356 | |
|
|
357 | This is the same thing as specifying C<sub { }> as callback, i.e. on |
|
|
358 | success, the results are ignored, while on failure, you the module dies |
|
|
359 | with a backtrace. |
|
|
360 | |
|
|
361 | This is good for quick scripts, or when you really aren't interested in |
|
|
362 | the results. |
|
|
363 | |
|
|
364 | =back |
|
|
365 | |
|
|
366 | =cut |
|
|
367 | |
302 | our $NOP_CB = sub { }; |
368 | our $NOP_CB = sub { }; |
303 | |
369 | |
304 | sub _txn { |
370 | sub _txn { |
305 | my ($name, $sub) = @_; |
371 | my ($name, $sub) = @_; |
306 | |
372 | |
307 | *{$name} = sub { |
373 | *{$name} = sub { |
308 | splice @_, 1, 0, (my $cv = AnyEvent->condvar); |
374 | my $cv = AE::cv; |
|
|
375 | |
|
|
376 | splice @_, 1, 0, $cv, sub { $cv->throw ($_[0]{extra_description}) }; |
309 | &$sub; |
377 | &$sub; |
310 | $cv->recv |
378 | $cv->recv |
311 | }; |
379 | }; |
312 | |
380 | |
313 | *{"$name\_"} = sub { |
381 | *{"$name\_"} = sub { |
|
|
382 | my ($ok, $err) = pop; |
|
|
383 | |
|
|
384 | if (ARRAY:: eq ref $ok) { |
|
|
385 | ($ok, $err) = @$ok; |
|
|
386 | } elsif (UNIVERSAL::isa $ok, AnyEvent::CondVar::) { |
|
|
387 | $err = sub { $ok->throw ($_[0]{extra_description}) }; |
|
|
388 | } else { |
|
|
389 | my $bt = Carp::longmess ""; |
|
|
390 | $err = sub { |
|
|
391 | die "$_[0]{extra_description}$bt"; |
|
|
392 | }; |
|
|
393 | } |
|
|
394 | |
|
|
395 | $ok ||= $NOP_CB; |
|
|
396 | |
314 | splice @_, 1, 0, pop || $NOP_CB; |
397 | splice @_, 1, 0, $ok, $err; |
315 | &$sub; |
398 | &$sub; |
316 | }; |
399 | }; |
317 | } |
400 | } |
318 | |
401 | |
|
|
402 | =over 4 |
|
|
403 | |
319 | =item $peers = $fcp->list_peers ([$with_metdata[, $with_volatile]]) |
404 | =item $peers = $fcp->list_peers ([$with_metdata[, $with_volatile]]) |
320 | |
405 | |
321 | =cut |
406 | =cut |
322 | |
407 | |
323 | _txn list_peers => sub { |
408 | _txn list_peers => sub { |
324 | my ($self, $cv, $with_metadata, $with_volatile) = @_; |
409 | my ($self, $ok, undef, $with_metadata, $with_volatile) = @_; |
325 | |
410 | |
326 | my @res; |
411 | my @res; |
327 | |
412 | |
328 | $self->send_msg (list_peers => |
413 | $self->send_msg (list_peers => |
329 | with_metadata => $with_metadata ? "true" : "false", |
414 | with_metadata => $with_metadata ? "true" : "false", |
330 | with_volatile => $with_volatile ? "true" : "false", |
415 | with_volatile => $with_volatile ? "true" : "false", |
331 | id_cb => sub { |
416 | id_cb => sub { |
332 | my ($self, $type, $kv, $rdata) = @_; |
417 | my ($self, $type, $kv, $rdata) = @_; |
333 | |
418 | |
334 | if ($type eq "end_list_peers") { |
419 | if ($type eq "end_list_peers") { |
335 | $cv->(\@res); |
420 | $ok->(\@res); |
336 | 1 |
421 | 1 |
337 | } else { |
422 | } else { |
338 | push @res, $kv; |
423 | push @res, $kv; |
339 | 0 |
424 | 0 |
340 | } |
425 | } |
… | |
… | |
345 | =item $notes = $fcp->list_peer_notes ($node_identifier) |
430 | =item $notes = $fcp->list_peer_notes ($node_identifier) |
346 | |
431 | |
347 | =cut |
432 | =cut |
348 | |
433 | |
349 | _txn list_peer_notes => sub { |
434 | _txn list_peer_notes => sub { |
350 | my ($self, $cv, $node_identifier) = @_; |
435 | my ($self, $ok, undef, $node_identifier) = @_; |
351 | |
436 | |
352 | $self->send_msg (list_peer_notes => |
437 | $self->send_msg (list_peer_notes => |
353 | node_identifier => $node_identifier, |
438 | node_identifier => $node_identifier, |
354 | id_cb => sub { |
439 | id_cb => sub { |
355 | my ($self, $type, $kv, $rdata) = @_; |
440 | my ($self, $type, $kv, $rdata) = @_; |
356 | |
441 | |
357 | $cv->($kv); |
442 | $ok->($kv); |
358 | 1 |
443 | 1 |
359 | }, |
444 | }, |
360 | ); |
445 | ); |
361 | }; |
446 | }; |
362 | |
447 | |
363 | =item $fcp->watch_global ($enabled[, $verbosity_mask]) |
448 | =item $fcp->watch_global ($enabled[, $verbosity_mask]) |
364 | |
449 | |
365 | =cut |
450 | =cut |
366 | |
451 | |
367 | _txn watch_global => sub { |
452 | _txn watch_global => sub { |
368 | my ($self, $cv, $enabled, $verbosity_mask) = @_; |
453 | my ($self, $ok, $err, $enabled, $verbosity_mask) = @_; |
369 | |
454 | |
370 | $self->send_msg (watch_global => |
455 | $self->send_msg (watch_global => |
371 | enabled => $enabled ? "true" : "false", |
456 | enabled => $enabled ? "true" : "false", |
372 | defined $verbosity_mask ? (verbosity_mask => $verbosity_mask+0) : (), |
457 | defined $verbosity_mask ? (verbosity_mask => $verbosity_mask+0) : (), |
373 | ); |
458 | ); |
374 | |
459 | |
375 | $cv->(); |
460 | $ok->(); |
376 | }; |
461 | }; |
377 | |
462 | |
378 | =item $reqs = $fcp->list_persistent_requests |
463 | =item $reqs = $fcp->list_persistent_requests |
379 | |
464 | |
380 | =cut |
465 | =cut |
381 | |
466 | |
382 | _txn list_persistent_requests => sub { |
467 | _txn list_persistent_requests => sub { |
383 | my ($self, $cv) = @_; |
468 | my ($self, $ok, $err) = @_; |
384 | |
469 | |
385 | $self->serialise (list_persistent_requests => sub { |
470 | $self->serialise (list_persistent_requests => sub { |
386 | my ($self, $guard) = @_; |
471 | my ($self, $guard) = @_; |
387 | |
472 | |
388 | my @res; |
473 | my @res; |
… | |
… | |
393 | my ($self, $type, $kv, $rdata) = @_; |
478 | my ($self, $type, $kv, $rdata) = @_; |
394 | |
479 | |
395 | $guard if 0; |
480 | $guard if 0; |
396 | |
481 | |
397 | if ($type eq "end_list_persistent_requests") { |
482 | if ($type eq "end_list_persistent_requests") { |
398 | $cv->(\@res); |
483 | $ok->(\@res); |
399 | return; |
484 | return; |
400 | } else { |
485 | } else { |
401 | my $id = $kv->{identifier}; |
486 | my $id = $kv->{identifier}; |
402 | |
487 | |
403 | if ($type =~ /^persistent_(get|put|put_dir)$/) { |
488 | if ($type =~ /^persistent_(get|put|put_dir)$/) { |
… | |
… | |
408 | 1 |
493 | 1 |
409 | }); |
494 | }); |
410 | }); |
495 | }); |
411 | }; |
496 | }; |
412 | |
497 | |
413 | =item $status = $fcp->remove_request ($global, $identifier) |
498 | =item $sync = $fcp->modify_persistent_request ($global, $identifier[, $client_token[, $priority_class]]) |
414 | |
499 | |
415 | =cut |
500 | Update either the C<client_token> or C<priority_class> of a request |
|
|
501 | identified by C<$global> and C<$identifier>, depending on which of |
|
|
502 | C<$client_token> and C<$priority_class> are not C<undef>. |
416 | |
503 | |
417 | _txn remove_request => sub { |
504 | =cut |
418 | my ($self, $cv, $global, $identifier) = @_; |
|
|
419 | |
505 | |
|
|
506 | _txn modify_persistent_request => sub { |
|
|
507 | my ($self, $ok, $err, $global, $identifier, $client_token, $priority_class) = @_; |
|
|
508 | |
|
|
509 | $self->serialise ($identifier => sub { |
|
|
510 | my ($self, $guard) = @_; |
|
|
511 | |
420 | $self->send_msg (remove_request => |
512 | $self->send_msg (modify_persistent_request => |
421 | global => $global ? "true" : "false", |
513 | global => $global ? "true" : "false", |
422 | identifier => $identifier, |
514 | identifier => $identifier, |
423 | id_cb => sub { |
515 | defined $client_token ? (client_token => $client_token ) : (), |
|
|
516 | defined $priority_class ? (priority_class => $priority_class) : (), |
|
|
517 | ); |
|
|
518 | |
|
|
519 | $self->on (sub { |
424 | my ($self, $type, $kv, $rdata) = @_; |
520 | my ($self, $type, $kv, @extra) = @_; |
425 | |
521 | |
|
|
522 | if ($kv->{identifier} eq $identifier) { |
|
|
523 | if ($type eq "persistent_request_modified") { |
426 | $cv->($kv); |
524 | $ok->($kv); |
|
|
525 | return; |
|
|
526 | } elsif ($type eq "protocol_error") { |
|
|
527 | $err->($kv); |
|
|
528 | return; |
|
|
529 | } |
|
|
530 | } |
|
|
531 | |
427 | 1 |
532 | 1 |
428 | }, |
533 | }); |
429 | ); |
534 | }); |
430 | }; |
535 | }; |
431 | |
536 | |
432 | =item $sync = $fcp->modify_persistent_request ($global, $identifier[, $client_token[, $priority_class]]) |
|
|
433 | |
|
|
434 | =cut |
|
|
435 | |
|
|
436 | _txn modify_persistent_request => sub { |
|
|
437 | my ($self, $cv, $global, $identifier, $client_token, $priority_class) = @_; |
|
|
438 | |
|
|
439 | $self->send_msg (modify_persistent_request => |
|
|
440 | global => $global ? "true" : "false", |
|
|
441 | defined $client_token ? (client_token => $client_token ) : (), |
|
|
442 | defined $priority_class ? (priority_class => $priority_class) : (), |
|
|
443 | identifier => $identifier, |
|
|
444 | id_cb => sub { |
|
|
445 | my ($self, $type, $kv, $rdata) = @_; |
|
|
446 | |
|
|
447 | $cv->($kv); |
|
|
448 | 1 |
|
|
449 | }, |
|
|
450 | ); |
|
|
451 | }; |
|
|
452 | |
|
|
453 | =item $info = $fcp->get_plugin_info ($name, $detailed) |
537 | =item $info = $fcp->get_plugin_info ($name, $detailed) |
454 | |
538 | |
455 | =cut |
539 | =cut |
456 | |
540 | |
457 | _txn get_plugin_info => sub { |
541 | _txn get_plugin_info => sub { |
458 | my ($self, $cv, $name, $detailed) = @_; |
542 | my ($self, $ok, $err, $name, $detailed) = @_; |
459 | |
543 | |
460 | $self->send_msg (get_plugin_info => |
544 | $self->send_msg (get_plugin_info => |
461 | plugin_name => $name, |
545 | plugin_name => $name, |
462 | detailed => $detailed ? "true" : "false", |
546 | detailed => $detailed ? "true" : "false", |
463 | id_cb => sub { |
547 | id_cb => sub { |
464 | my ($self, $type, $kv, $rdata) = @_; |
548 | my ($self, $type, $kv, $rdata) = @_; |
465 | |
549 | |
466 | $cv->($kv); |
550 | $ok->($kv); |
467 | 1 |
551 | 1 |
468 | }, |
552 | }, |
469 | ); |
553 | ); |
470 | }; |
554 | }; |
471 | |
555 | |
… | |
… | |
478 | binary_blob, allowed_mime_types, filename, temp_filename |
562 | binary_blob, allowed_mime_types, filename, temp_filename |
479 | |
563 | |
480 | =cut |
564 | =cut |
481 | |
565 | |
482 | _txn client_get => sub { |
566 | _txn client_get => sub { |
483 | my ($self, $cv, $uri, $identifier, %kv) = @_; |
567 | my ($self, $ok, $err, $uri, $identifier, %kv) = @_; |
484 | |
568 | |
485 | $self->send_msg (client_get => |
569 | $self->send_msg (client_get => |
486 | %kv, |
570 | %kv, |
487 | uri => $uri, |
571 | uri => $uri, |
488 | identifier => $identifier, |
572 | identifier => $identifier, |
489 | ); |
573 | ); |
|
|
574 | |
|
|
575 | $ok->(); |
490 | }; |
576 | }; |
491 | |
577 | |
492 | =item $status = $fcp->remove_request ($identifier[, $global]) |
578 | =item $status = $fcp->remove_request ($identifier[, $global]) |
493 | |
579 | |
494 | Remove the request with the given isdentifier. Returns true if successful, |
580 | Remove the request with the given isdentifier. Returns true if successful, |
495 | false on error. |
581 | false on error. |
496 | |
582 | |
497 | =cut |
583 | =cut |
498 | |
584 | |
499 | _txn remove_request => sub { |
585 | _txn remove_request => sub { |
500 | my ($self, $cv, $identifier, $global) = @_; |
586 | my ($self, $ok, $err, $identifier, $global) = @_; |
501 | |
587 | |
502 | $self->serialise ($identifier => sub { |
588 | $self->serialise ($identifier => sub { |
503 | my ($self, $guard) = @_; |
589 | my ($self, $guard) = @_; |
504 | |
590 | |
505 | $self->send_msg (remove_request => |
591 | $self->send_msg (remove_request => |
… | |
… | |
509 | $self->on (sub { |
595 | $self->on (sub { |
510 | my ($self, $type, $kv, @extra) = @_; |
596 | my ($self, $type, $kv, @extra) = @_; |
511 | |
597 | |
512 | if ($kv->{identifier} eq $identifier) { |
598 | if ($kv->{identifier} eq $identifier) { |
513 | if ($type eq "persistent_request_removed") { |
599 | if ($type eq "persistent_request_removed") { |
514 | $cv->(1); |
600 | $ok->(1); |
515 | return; |
601 | return; |
516 | } elsif ($type eq "protocol_error") { |
602 | } elsif ($type eq "protocol_error") { |
517 | $cv->(undef); |
603 | $err->($kv); |
518 | return; |
604 | return; |
519 | } |
605 | } |
520 | } |
606 | } |
521 | |
607 | |
522 | 1 |
608 | 1 |
… | |
… | |
548 | directory. |
634 | directory. |
549 | |
635 | |
550 | =cut |
636 | =cut |
551 | |
637 | |
552 | _txn test_dda => sub { |
638 | _txn test_dda => sub { |
553 | my ($self, $cv, $local, $remote, $want_read, $want_write) = @_; |
639 | my ($self, $ok, $err, $local, $remote, $want_read, $want_write) = @_; |
554 | |
640 | |
555 | $self->serialise (test_dda => sub { |
641 | $self->serialise (test_dda => sub { |
556 | my ($self, $guard) = @_; |
642 | my ($self, $guard) = @_; |
557 | |
643 | |
558 | $self->send_msg (test_dda_request => |
644 | $self->send_msg (test_dda_request => |
… | |
… | |
599 | my ($self, $type, $kv) = @_; |
685 | my ($self, $type, $kv) = @_; |
600 | |
686 | |
601 | $guard if 0; # reference |
687 | $guard if 0; # reference |
602 | |
688 | |
603 | if ($type eq "test_dda_complete") { |
689 | if ($type eq "test_dda_complete") { |
604 | $cv->( |
690 | $ok->( |
605 | $kv->{read_directory_allowed} eq "true", |
691 | $kv->{read_directory_allowed} eq "true", |
606 | $kv->{write_directory_allowed} eq "true", |
692 | $kv->{write_directory_allowed} eq "true", |
607 | ); |
693 | ); |
608 | } elsif ($type eq "protocol_error" && $kv->{identifier} eq $remote) { |
694 | } elsif ($type eq "protocol_error" && $kv->{identifier} eq $remote) { |
609 | $cv->croak ($kv->{extra_description}); |
695 | $err->($kv->{extra_description}); |
610 | return; |
696 | return; |
611 | } |
697 | } |
612 | |
698 | |
613 | 1 |
699 | 1 |
614 | }); |
700 | }); |
615 | |
701 | |
616 | return; |
702 | return; |
617 | } elsif ($type eq "protocol_error" && $kv->{identifier} eq $remote) { |
703 | } elsif ($type eq "protocol_error" && $kv->{identifier} eq $remote) { |
618 | $cv->croak ($kv->{extra_description}); |
704 | $err->($kv); |
619 | return; |
705 | return; |
620 | } |
706 | } |
621 | |
707 | |
622 | 1 |
708 | 1 |
623 | }); |
709 | }); |