The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache::AppCluster::Client

SYNOPSIS

  #To call a single remote method:
  
  use Apache::AppCluster::Client;
  my $client = Apache::AppCluster::Client->new();
  
  $client->add_request(
    key => 'key1',
    method => 'MyLib::search()',
    params => ['val1', 'val2', 'another_val', 'more_stuff'],
    url => 'http://your.servername.com:8080/search',
  );
  
  my $timeout = 5.6; #seconds - can be a float
  my $num_succesful = $client->send_requests($timeout);
  my $num_failed = $client->get_total_failed();
  
  if($client->request_ok('key1')) {
    my $key1_data = $client->get_request_data('key1');
  } else {
    print "Request 'key1' failed with error: " . 
      $client->translate_error($client->get_request_status('key1'));
  }

          -OR-
          
  #To call many remote methods on distributed servers simultaneously:
  use Apache::AppCluster::Client;
  
  my $client = Apache::AppCluster::Client->new();
  
  my @servers = qw( server1.cluster.com server2.cluster.com 
     server3.cluster.com server4.cluster.com );
  
  for(my $counter = 0; $counter < 4000; $counter += 4) {
    my $server_url = 'http://' . $servers[$counter % 4] . '/server_uri';
    
    $client->add_request(
      key => $counter,
      #Method and params can vary per request
      method => 'MyLib::do_something()', 
      params => { key1 => 'value1', key2 => 'value2' },
      url => $server_url,
    );
  }

  my $num_succesful = $client->send_requests(60);
  my $num_failed = $client->get_total_failed();
  
  my %data;
  for(my $counter = 0; $counter < 4000; $counter++) {
    if($client->request_ok($counter)) {
      $data{$counter} = $client->get_request_data($counter);
    } else {
      $data{$counter} = undef;
    }
  }

  print "Total time for all requests to finish: " . 
    $client->get_total_request_time();
        

DESCRIPTION

Apache::AppCluster::Client is designed to be a lightweight RPC mechanism for mod_perl applications that allows concurrent method calls to multiple remote mod_perl application servers. If you simply want a mod_perl app to do 20 things at once locally, or you have a cluster of 100 distributed mod_perl web servers acting as back end processors for a front end web server, you'll (hopefully) find this useful.

THE CLIENT OBJECT

The client object is created by calling new with no parameters. Then call add_request() to add as many requests as you like specifying a request key each time. Then call send_requests($timeout) to send all requests simultaneously to their respective remote servers. The return data for each request can be retreived using get_request_data($request_key).

METHODS

The following methods may be called on the client object.

new()

Creates a client object - takes no parameters.

add_request()

$client->add_request( key => $keyname, method => 'MyLib::MainModule::method()', params => $scalar_reference, url => 'http://server.mydomain.com:8080/svr_uri', );

Add request registers a request to be sent to a remote server with the client object. 'key' may be any key that may be used in a hash. 'method' is the name of the remote method you wish to invoke including full package name and brackets. 'params' is any scalar. The scalar may contain a reference to a HASH, ARRAY, object, or anything that Storable::freeze and Storable::thaw can serialize. 'url' is a URL in standard format. You may optionally specify a remote port. If none is specified, it defaults to 80 as per normal. The URI portion of the URL (/svr_uri in the example) must point to the URI that is handled by Apache::AppCluster::Server. Please see the latters documentation for details.

$n = send_requests($timeout)

Send requests must be called with a timeout in seconds. The timeout can be a floating point number. The return value is the number of requests succesfully returned. All requests that have been registered with add_request will be sent simultaneously to their respective servers when send_requests is called. send_requests will return when all responses have been received or the specified timeout has elapsed. If the timeout is 0 or omitted, then send_requests will wait an infinite time for a response.

NOTE that when you call send_requests, a socket will be created for each request to be sent. Please make sure you have enough sockets available i.e. don't try to send 100000 requests simultaneously. Also note that the client first establishes a connection to all remote servers, then sends the requests. If you are connecting to a single server, make sure you dont overload it with connections, or you will find all your requests timing out i.e. Don't exceed your apache server's MaxClient's setting.

get_total_failed()

Returns the number of failed requests.

get_total_success()

Returns number of succesful requests.

request_ok($key)

Returns true if the request associated with $key was succesful

get_request_data($key)

Returns the data that was returned from the request associated with $key. Returns undef if there is no such request and false if there is no data (which would be the case if the request failed). If you have a function that returns false, then have it return a reference that points to a false value.

get_total_request_time()

Returns the total time taken to process all requests. You can call this after you call send_requests.

request_status($key)

Returns a numerical status for the request.

translate_error(request_status($key))

translate_error() will translate the numerical status returned by request_status().

get_request_keys()

Returns an array of all keys for all requests added using add_request().

BUGS

None yet. Please send to mark@swiftcamel.com

SEE ALSO

Apache::AppCluster::Server

AUTHOR

Mark Maunder <mark@swiftcamel.com> - Any problems, bugs, feature requests or questions are welcome.