NAME
    WebService::Async - Non-blocking interface to web service APIs

SYNOPSIS
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
          on_done         => sub {
              my ($service, $id, $res, $req) = @_;
              print $req->param->{'q'} . " => ";
              print "$res->{responseData}->{translatedText}\n";
          },
      );
      $wa->add_get( q => 'apple' );
      $wa->add_get( q => 'orange' );
      $wa->add_get( q => 'banana', langpair => 'en|fr' );
      $wa->send_request;    # sending three requests in parallel.

      Results below.
        orange => arancione
        banana => la banane
        apple => mela

DESCRIPTION
    WebService::Async is a non-blocking interface to web service APIs.

    This is similar to WebService::Simple but this is a non-blocking one.

    So this module helps "PSGI/Plack streaming" programming with Tatsumaki
    and Gearman. See example 11.

    *   Easy to use asynchronous request.

    *   Caching with memcached.

    *   Retrying automatically on error.

    *   Logging with Log::Dispatch::Config (starting connection, storing
        cache, cache hit, etc...)

    *   Flexibly customizable.

EXAMPLES
    Here is 11 simple examples.

  Example 1. A very simple "Synchronous Request" pattern
    Here is a very simple usage.

    It is almost the same as "WebService::Simple" module.

   SOURCE
      use WebService::Async;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
      );
      my $ret = $wa->get( q => 'hello' ); # send get request
      print $ret->get;

   RESULTS
      {"responseData": {"translatedText":"ciao"}, "responseDetails": null, "responseStatus": 200}

  Example 2. "Synchronous Request" with a response parser
    It is almost the same as "WebService::Simple" module.

   SOURCE
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
      );
      my $ret = $wa->get( q => 'hello' );    # send get request
      print $ret->get->{responseData}->{translatedText};

   RESULTS
      ciao

  Example 3. Asynchronous request
    You have to get or create the access-key which relates the response to
    the request.

   SOURCE
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
      );
  
      # USING THE AUTOMATIC GENERATED KEY
      my $apple_key  = $wa->add_get( q => 'apple' );
      my $orange_key = $wa->add_get( q => 'orange' );
      my $grape_key  = $wa->add_get( q => 'grape' );
      my $ret = $wa->send_request;
      # blocking here automatically and sending 3 asynchronous requests.
      print $ret->get($orange_key)->{responseData}->{translatedText} . "\n";
  
      # USING YOUR OWN SPECIFIED KEY
      $wa->add_get(id => 1, param => { q => 'pear' });
      $wa->add_get(id => 2, param => { q => 'banana'});
      $wa->add_get(id => 3, lang => 'fr', param => { q => 'cherry', langpair => 'en|fr' });
      $ret = $wa->send_request;
      # blocking here automatically and sending 3 asynchronous requests.
      print $ret->get([id => 3, lang => 'fr'])->{responseData}->{translatedText}. "\n";

   RESULTS
      arancione
      cerise

  Example 4. Asyncronous request with callback
    You can get results in your own callback function.

   SOURCE
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
          on_done         => sub {
              my ( $async, $keys, $result ) = @_;
              print "on_done =>"
                . " key(@{$keys}):"
                . " value($result->{responseData}->{translatedText})\n";
          },
          on_complete => sub {
              my ( $async, $result ) = @_;
              print "on_complete\n";
              for ( $result->keys ) {
                  print "  key(@{$_}): value("
                    . $result->get($_)->{responseData}->{translatedText} . ")\n";
              }
          },
      );
      $wa->add_get( id => 1, param => { q => 'apple' } );
      $wa->add_get(
          id    => 2,
          param => { q => 'orange' },
          sub { print "on_done => override!\n" }
      );
      $wa->add_get(
          id    => 3,
          lang  => 'fr',
          param => { q => 'grape', langpair => 'en|fr' }
      );
  
      $wa->send_request;
      # blocking here automatically and sending 3 asynchronous requests.

   RESULTS
      on_done => key(id 3 lang fr): value(raisins)
      on_done => override!
      on_done => key(id 1): value(mela)
      on_complete
        key(id 2): value(arancione)
        key(id 3 lang fr): value(raisins)
        key(id 1): value(mela)

  Example 5. Asyncronous Request without auto blocking
    If you are familiar with AnyEvent, you can use non-blocking
    'send_request';

    This usage is useful when you want to access two or more sites at the
    same time.

   SOURCE
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      my $cv = AE::cv;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
          on_complete     => \&on_complete,
          auto_block      => 0, # change block mode to manual
      );
  
      sub on_complete {
          my ( $async, $result ) = @_;
          print "on_complete\n";
          for my $key ( $result->keys ) {
              my $text = $result->get($key)->{responseData}->{translatedText};
              print "  key(@{${key}}): value(${text})\n";
          }
          $cv->send;
      }
  
      $wa->add_get( id => 1, param => { q => 'apple' } );
      $wa->add_get( id => 2, param => { q => 'orange' } );
      $wa->add_get( id => 3, param => { q => 'grape' } );
      $wa->send_request;
      $cv->recv;    # You have to block by your responsibility.

   RESULTS
      on_complete
        key(id 2): value(arancione)
        key(id 3): value(uva)
        key(id 1): value(mela)

  Example 6. Logging
    If you want to using automatic logging, sets the Log::Dispatch instance
    to the logger attribute.

   SOURCE
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      use FindBin qw($Bin);
  
      use Log::Dispatch::Config;
      use Log::Dispatch::Configurator::YAML;
      my $configure =
        Log::Dispatch::Configurator::YAML->new("${Bin}/log_config.yaml");
      Log::Dispatch::Config->configure($configure);
      my $logger = Log::Dispatch::Config->instance;
  
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
          on_complete     => \&on_complete,
          logger          => $logger,
      );
  
      sub on_complete {
          my ( $async, $result ) = @_;
          print "on_complete\n";
          for my $key ( $result->keys ) {
              my $text = $result->get($key)->{responseData}->{translatedText};
              print "  key(@{${key}}): value(${text})\n";
          }
      }
  
      $wa->add_get( id => 1, param => { q => 'apple' } );
      $wa->add_get( id => 2, param => { q => 'orange' } );
      $wa->add_get( id => 3, param => { q => 'grape' } );
      $wa->send_request;

   RESULTS
      [Tue Sep 28 15:48:48 2010] [info] Invoke 'add_get' method. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Push a request into the request queue. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Invoke 'add_get' method. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Push a request into the request queue. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Invoke 'add_get' method. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Push a request into the request queue. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Invoke 'send_request' method. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Start processing request queue. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Set the busy flag is true. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Start processing request: http://ajax.googleapis.com/ajax/services/language/translate?q=grape&v=1.0&langpair=en%7Cit?q=grape&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Does not hit any caches: http://ajax.googleapis.com/ajax/services/language/translate?q=grape&v=1.0&langpair=en%7Cit?q=grape&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Start processing request: http://ajax.googleapis.com/ajax/services/language/translate?q=orange&v=1.0&langpair=en%7Cit?q=orange&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Does not hit any caches: http://ajax.googleapis.com/ajax/services/language/translate?q=orange&v=1.0&langpair=en%7Cit?q=orange&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Start processing request: http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cit?q=apple&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [info] Does not hit any caches: http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cit?q=apple&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Invoking http_request method [first time] (method=GET url=http://ajax.googleapis.com/ajax/services/language/translate?q=grape&v=1.0&langpair=en%7Cit). at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Invoking http_request method [first time] (method=GET url=http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cit). at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:48 2010] [debug] Invoking http_request method [first time] (method=GET url=http://ajax.googleapis.com/ajax/services/language/translate?q=orange&v=1.0&langpair=en%7Cit). at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:49 2010] [debug] Receive a response from http://ajax.googleapis.com/ajax/services/language/translate?q=orange&v=1.0&langpair=en%7Cit?q=orange&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:49 2010] [debug] Parse a response. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:49 2010] [debug] Set a parsed response into the internal store. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:49 2010] [debug] Convert a parsed response to the specified format. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:49 2010] [info] One request is successfully completed. Execute 'on_done' callback. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Receive a response from http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cit?q=apple&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Parse a response. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Set a parsed response into the internal store. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Convert a parsed response to the specified format. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [info] One request is successfully completed. Execute 'on_done' callback. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Receive a response from http://ajax.googleapis.com/ajax/services/language/translate?q=grape&v=1.0&langpair=en%7Cit?q=grape&v=1.0&langpair=en%7Cit at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Parse a response. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Set a parsed response into the internal store. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] Convert a parsed response to the specified format. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [info] One request is successfully completed. Execute 'on_done' callback. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] The request is successfully completed. Clear the busy flag. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [debug] The request is successfully completed. Clear all parsed responses. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Tue Sep 28 15:48:51 2010] [info] All the request is successfully completed. Execute 'on_complete' callback. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
  
      on_complete
        key(id 2): value(arancione)
        key(id 3): value(uva)
        key(id 1): value(mela)

  Example 7. Asyncronous Request with response converter
    You can customize the response by using a custom function or existing
    converter classes like WebService::Async::Converter::XMLSimple.

   SOURCE
      use Text::MicroTemplate::DataSection 'render_mt';
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      use WebService::Async::Converter::XMLSimple;
      use WebService::Async::Converter::Function;
  
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => { v => '1.0', langpair => 'en|it' },
          response_parser => WebService::Async::Parser::JSON->new,
          on_done         => sub {
              my ( $sv, $id, $result ) = @_;
              print "${result}\n";
          },
      );
  
      # It is useless because you can not relate the request to the response.
      # See the "Expected results below".
      $wa->response_converter( WebService::Async::Converter::XMLSimple->new );
  
      # You can customize the response by using a custom function.
      $wa->whole_response_converter(
          WebService::Async::Converter::Function->new( converter => \&_converter ) );
      sub _converter {
          my ( $sv, $request, $parsed_response ) = @_;
          my $converted_reponse =
            render_mt( 'whole_template', $parsed_response )->as_string;
          return $converted_reponse;
      }
  
      # translating
      $wa->add_get( id => 1, lang => 'fr', param => { q => 'apple', langpair => 'en|fr' } );
      $wa->add_get( id => 2, lang => 'it', param => { q => 'orange' } );
      $wa->add_get( id => 3, lang => 'it', param => { q => 'grape' } );
      my $result = $wa->send_request;
      print "${result}\n";
  
      __DATA__
      @@ whole_template
      <results>
      ? for my $key ($_[0]->keys_as_hash) {
      ?   my $text = $_[0]->get($key)->{responseData}->{translatedText};
          <translated id="<?= $key->{id} ?>" lang="<?= $key->{lang} ?>"><?= $text ?></translated>
      ? }
      </results>

   RESULTS
      --- Output from on_done.
      --- It is useless because you can not relate the request to the response.
      <?xml version="1.0" encoding="UTF-8"?>
      <result>
        <responseData>
          <translatedText>mela</translatedText>
        </responseData>
        <responseDetails></responseDetails>
        <responseStatus>200</responseStatus>
      </result>
  
      <?xml version="1.0" encoding="UTF-8"?>
      <result>
        <responseData>
          <translatedText>uva</translatedText>
        </responseData>
        <responseDetails></responseDetails>
        <responseStatus>200</responseStatus>
      </result>
  
      <?xml version="1.0" encoding="UTF-8"?>
      <result>
        <responseData>
          <translatedText>arancione</translatedText>
        </responseData>
        <responseDetails></responseDetails>
        <responseStatus>200</responseStatus>
      </result>
      ---
  
      --- Output from send_request
      --- Relating the request to the resposne by using the key.
      <results>
          <translated id="3" lang="it">uva</translated>
          <translated id="1" lang="fr">Apple</translated>
          <translated id="2" lang="it">arancione</translated>
      </results>
      ---

  Example 8. Caching with memcached
    You can cache the responses by using Cache::Memcached.

    The log is outputted when the cache stores or retrieves.

   SOURCE
      use Cache::Memcached;
      use WebService::Async;
      use WebService::Async::Parser::JSON;
      use WebService::Async::ResponseCache;
  
      use FindBin qw($Bin);
      use Log::Dispatch::Config;
      use Log::Dispatch::Configurator::YAML;
      my $configure =
        Log::Dispatch::Configurator::YAML->new("${Bin}/log_config.yaml");
      Log::Dispatch::Config->configure($configure);
      my $logger = Log::Dispatch::Config->instance;
  
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => {
              v        => '1.0',
              langpair => 'en|fr',
          },
          auto_block      => 1,
          response_parser => WebService::Async::Parser::JSON->new,
          logger          => $logger,
      );
      $wa->response_cache(
          WebService::Async::ResponseCache->new(
              cache => Cache::Memcached->new( { servers => ['localhost:11211'] } )
          )
      );
      $wa->add_get(
          id    => 1,
          lang  => 'en',
          param => { q => 'apple' }
      );
      $wa->add_get(
          id    => 2,
          lang  => 'en',
          param => { q => 'banana' }
      );
      my $result = $wa->send_request();

   RESULTS
      -- First time execution: setting caches.
      [Wed Sep 29 10:23:25 2010] [info] Does not hit any caches: http://ajax.googleapis.com/ajax/services/language/translate?q=banana&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Wed Sep 29 10:23:25 2010] [info] Does not hit any caches: http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Wed Sep 29 10:23:25 2010] [debug] Cache set at: http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Wed Sep 29 10:23:27 2010] [debug] Cache set at: http://ajax.googleapis.com/ajax/services/language/translate?q=banana&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
  
      -- Second time execution: retrieving from caches.
      [Wed Sep 29 10:12:52 2010] [info] Cache hit: http://ajax.googleapis.com/ajax/services/language/translate?q=banana&v=1.0&langpair=en%7Cfr?q=banana&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111
      [Wed Sep 29 10:12:52 2010] [info] Cache hit: http://ajax.googleapis.com/ajax/services/language/translate?q=apple&v=1.0&langpair=en%7Cfr?q=apple&v=1.0&langpair=en%7Cfr at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 111

  Example 9. Handling exceptions
    This is a list of the prohibited matter.

   SOURCE
      use Try::Tiny;
      use WebService::Async;
      my $cv = AE::cv;
      my $wa = WebService::Async->new(
          base_url => 'http://ajax.googleapis.com/ajax/services/language/translate',
          param    => {
              v        => '1.0',
              langpair => 'en|fr',
          },
          auto_block => 0,
      );
      $wa->add_get( q  => 'apple' );
      $wa->add_get( id => 1, param => { q => 'banana' } );
  
      # The requst key is duplicate.
      try {
          $wa->add_get( id => 1, param => { q => 'banana' } );
      }
      catch {
          warn $_;
      };
      $wa->send_request;
  
      # Cannot change the 'auto_block' attribute while the request queue is processing.
      try {
          $wa->auto_block(1);
      }
      catch {
          warn $_;
      };
  
      # Cannnot send the another request while the request queue is processing.
      try {
          $wa->send_request;
      }
      catch {
          warn $_;
      };
  
      # If the status code of the response header is /^2/,
      # throws "HTTP connection error occurred. The status code is '%s'." exception.

   RESULTS
      The requst key is duplicate. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 198
          WebService::Async::_add_request('WebService::Async=HASH(0xa086778)', 'GET', 'id', 1, 'param', 'HASH(0xa53db30)') called at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 76
          WebService::Async::add_get('WebService::Async=HASH(0xa086778)', 'id', 1, 'param', 'HASH(0xa53db30)') called at examples/example9.pl line 23
          main::__ANON__() called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 76
          eval {...} called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 67
          Try::Tiny::try('CODE(0xa08ebd0)', 'Try::Tiny::Catch=REF(0xa4fce78)') called at examples/example9.pl line 27
  
      Cannot change the 'auto_block' attribute while the request queue is processing. at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 43
          Class::MOP::Class:::before('WebService::Async=HASH(0xa086778)', 1) called at /opt/perl/lib/site_perl/5.10.0/i686-linux-thread-multi/Class/MOP/Method/Wrapped.pm line 47
          Class::MOP::Method::Wrapped::__ANON__('WebService::Async=HASH(0xa086778)', 1) called at /opt/perl/lib/site_perl/5.10.0/i686-linux-thread-multi/Class/MOP/Method/Wrapped.pm line 89
          WebService::Async::auto_block('WebService::Async=HASH(0xa086778)', 1) called at examples/example9.pl line 32
          main::__ANON__() called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 76
          eval {...} called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 67
          Try::Tiny::try('CODE(0xa51a330)', 'Try::Tiny::Catch=REF(0xa53dab0)') called at examples/example9.pl line 36
  
      Cannot send the another request while the request queue is processing. at /opt/perl/lib/site_perl/5.10.0/WebService/Async/Role/RequestProcessor.pm line 221
          WebService::Async::Role::RequestProcessor::_process_request_queue('WebService::Async=HASH(0xa086778)') called at /opt/perl/lib/site_perl/5.10.0/WebService/Async.pm line 93
          WebService::Async::send_request('WebService::Async=HASH(0xa086778)') called at examples/example9.pl line 40
          main::__ANON__() called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 76
          eval {...} called at /opt/perl/lib/site_perl/5.10.0/Try/Tiny.pm line 67
          Try::Tiny::try('CODE(0xa51a330)', 'Try::Tiny::Catch=REF(0xa51ae20)') called at examples/example9.pl line 44

  Example 10. Subclassing
    See WebService::Async::Google::TranslateV1_0

  Example 11. Proxy Server for Google Translation Service.
    This is a more complicated example using Plack, Tatsumaki and
    Subclassing(WebService::Async::Google::TranslateV1_0).

   SOURCE
      package Translation;
      use Moose;
      extends 'Tatsumaki::Handler';
  
      use Tatsumaki::Application;
      use Encode qw(decode_utf8);
      use WebService::Async::Google::TranslateV1_0;
  
      __PACKAGE__->asynchronous(1);
  
      sub get {
          translate(@_);
      }
  
      sub post {
          translate(@_);
      }
  
      sub translate {
          my ( $self, $arg ) = shift;
          $self->response->content_type('text/xml');
          my $req    = $self->request;
          my $params = $req->parameters;
          my $src    = $params->get('f');
          $params->remove('f');
          my $dest = $params->get('t');
          $params->remove('t');
  
          if ( !defined $src || !defined $dest ) {
              # TODO throws an exception.
          }
          my @dest = split '\|', $dest;
          if ( !@dest ) {
              # TODO throws an exception.
          }
          my $service = WebService::Async::Google::TranslateV1_0->new;
          $service->source_language($src);
          $service->set_destination_languages(@dest);
          $params->each(
              sub {
                  $service->set_message( decode_utf8( $_[0] ), $_[1] );
              }
          );
          $service->translate(
              on_each_translation => sub {
                  my ( $sv, $id, $res ) = @_;
                  $self->stream_write($res);
              },
              on_translation_complete => sub {
                  my ( $atg, $all_res ) = @_;
                  $self->stream_write($all_res);
                  $self->finish;
              },
          );
      }
  
      my $app = Tatsumaki::Application->new( [
            '/translation/api/get' => 'Translation'
            ] );
      return $app;

METHODS
  new(%opt)
    Constructor. Create WebService::Async instance.

    Available options are:

    base_url
        Base url exclude query strings.

    param
        Query parameters. HashRef.

    auto_block
        1 or 0. Auto blocking or not.

    max_per_host
        Maximum per host. $AnyEvent::HTTP::MAX_PER_HOST.

    timeout
        Seconds.

    retry_interval
        Seconds.

    max_retry_count
        If given three, retrying three times on connection error.

    response_parser
        WebService::Async::Parser::* instance.

    response_converter
        WebService::Async::Converter::* instance.

    whole_response_converter
        WebService::Async::Converter::* instance.

    logger
        Log::Dispatch instance.

    user_agent
        User agent name or alias. Alias can be 'Windows IE 6', 'Windows
        Mozilla', 'Mac Safari', 'Mac Mozilla', 'Linux Mozilla', 'Linux
        Konqueror'.

    on_done
        A code reference invoking when a request is done.

    on_complete
        A code reference invoking when all requests is completed.

    on_error
        A code reference invoking when the error occurs.

    on_critical_error
        A code reference invoking when the critical error occurs.

    check_error
        A code reference for checking errors.

    critical_error_message
        This is a message that replaces the converted response when the
        critical error occurs.

        See WebService::Async::Google::TranslateV1_0

  get
    Sending a get request and blocking. Returns a converted response. This
    method is synchronous use only.

  post
    Sending a post request and blocking. Returns a converted response. This
    method is synchronous use only.

  add_get
    Creating a get request and queuing it. Returns a array reference which
    includes key for access the response.

  add_post
    Creating a post request and queuing it. Returns a array reference which
    includes key for access the response.

  send_request
    Sending all queued requests and blocking; Returns a converted response.

SUBCLASSING
    For better encapsulation, you can create subclass of WebService::Async
    to customize the behavior.

    See WebService::Async::Google::TranslateV1_0.

PARSERS
    If you want to use an existing parsers, see example 2.

    Or if you want to create your own parsers such as a
    WebService::Async::Parser::MessagePack, see
    WebService::Async::Parser::JSON.

CACHING
    See example 8.

DIAGNOSTICS
    Cannot send the another request while the request queue is processing.
        Once you run 'send_request' method, you can not run another one
        until 'send_request' is finished.

    The requst key is duplicate.
        You must avoid to duplicating keys on using 'add_get' or 'add_post'
        method.

    Cannot change the 'auto_block' attribute while the request queue is
    processing.
        You can not change the 'auto_block' attribute while the request
        queue is processing.

    HTTP connection error occurred. The status code is '%s'.
        Throws If the status code of the response header is not /^2/.

DEPENDENCIES
    AnyEvent
    AnyEvent::HTTP
    Clone
    Data::UUID
    Data::Section::Simple
    Encode
    Hash::MultiKey
    JSON
    Log::Dispatch::Config
    Moose
    MooseX::WithCache
    Regexp::Common
    Scalar::Util
    Smart::Args;
    Try::Tiny
    URI::Escape
    XML::Simple
    Plack::Loader
    Plack::Request
    Test::Deep
    Test::Exception
    Test::TCP
    Text::MicroTemplate
    Text::MicroTemplate::DataSection
    UNIVERSAL

POD BUGS
    This POD does'nt make sense because my English Sux.

    The best way to understand the usage of this module is reading the
    "SYNOPSIS" and "EXAMPLES" section.

GIT REPOSITORY
    http://github.com/keroyonn/p5-WebService-Async

AUTHOR
    keroyonn <keroyon@cpan.org>

SEE ALSO
    WebService::Simple
    Tatsumaki

LICENSE
    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

