Class MCollective::RPC::Client
In: lib/mcollective/rpc/client.rb
Parent: Object

The main component of the Simple RPC client system, this wraps around MCollective::Client and just brings in a lot of convention and standard approached.

Methods

Attributes

agent  [R] 
batch_mode  [R] 
batch_size  [R] 
batch_sleep_time  [R] 
client  [R] 
config  [RW] 
ddl  [R] 
default_discovery_method  [R] 
discovery_method  [R] 
discovery_options  [R] 
filter  [RW] 
limit_method  [R] 
limit_seed  [R] 
limit_targets  [R] 
output_format  [R] 
progress  [RW] 
reply_to  [RW] 
stats  [R] 
timeout  [RW] 
ttl  [RW] 
verbose  [RW] 

Public Class methods

Creates a stub for a remote agent, you can pass in an options array in the flags which will then be used else it will just create a default options array with filtering enabled based on the standard command line use.

  rpc = RPC::Client.new("rpctest", :configfile => "client.cfg", :options => options)

You typically would not call this directly you‘d use MCollective::RPC#rpcclient instead which is a wrapper around this that can be used as a Mixin

Public Instance methods

Sets the agent filter

Sets the batch size, if the size is set to 0 that will disable batch mode

Handles traditional calls to the remote agents with full stats blocks, non blocks and everything else supported.

Other methods of calling the nodes can reuse this code by for example specifying custom options and discovery data

Calls an agent in a way very similar to call_agent but it supports batching the queries to the network.

The result sets, stats, block handling etc is all exactly like you would expect from normal call_agent.

This is used by method_missing and works only with direct addressing mode

Sets the class filter

Sets the collective we are communicating with

Set a compound filter

Constructs custom requests with custom filters and discovery data the idea is that this would be used in web applications where you might be using a cached copy of data provided by a registration agent to figure out on your own what nodes will be responding and what your filter would be.

This will help you essentially short circuit the traditional cycle of:

mc discover / call / wait for discovered nodes

by doing discovery however you like, contructing a filter and a list of nodes you expect responses from.

Other than that it will work exactly like a normal call, blocks will behave the same way, stats will be handled the same way etcetc

If you just wanted to contact one machine for example with a client that already has other filter options setup you can do:

puppet.custom_request("runonce", {}, ["your.box.com"], {:identity => "your.box.com"})

This will do runonce action on just ‘your.box.com’, no discovery will be done and after receiving just one response it will stop waiting for responses

If direct_addressing is enabled in the config file you can provide an empty hash as a filter, this will force that request to be a directly addressed request which technically does not need filters. If you try to use this mode with direct addressing disabled an exception will be raise

Disconnects cleanly from the middleware

Does discovery based on the filters set, if a discovery was previously done return that else do a new discovery.

Alternatively if identity filters are given and none of them are regular expressions then just use the provided data as discovered data, avoiding discovery

Discovery can be forced if direct_addressing is enabled by passing in an array of nodes with :nodes or JSON data like those produced by mcollective RPC JSON output using :json

Will show a message indicating its doing discovery if running verbose or if the :verbose flag is passed in.

Use reset to force a new discovery

Sets the discovery method. If we change the method there are a number of steps to take:

 - set the new method
 - if discovery options were provided, re-set those to initially
   provided ones else clear them as they might now apply to a
   different provider
 - update the client options so it knows there is a new discovery
   method in force
 - reset discovery data forcing a discover on the next request

The remaining item is the discovery timeout, we leave that as is since that is the user supplied timeout either via initial options or via specifically setting it on the client.

for requests that do not care for results just return the request id and don‘t do any of the response processing.

We send the :process_results flag with to the nodes so they can make decisions based on that.

Should only be called via method_missing

Returns help for an agent if a DDL was found

Sets the identity filter

if an identity filter is supplied and it is all strings no regex we can use that as discovery data, technically the identity filter is then redundant if we are in direct addressing mode and we could empty it out but this use case should only really be for a few -I‘s on the CLI

For safety we leave the filter in place for now, that way we can support this enhancement also in broadcast mode.

This is only needed for the ‘mc’ discovery method, other methods might change the concept of identity to mean something else so we should pass the full identity filter to them

Sets and sanity check the limit_method variable used to determine how to limit targets if limit_targets is set

Sets and sanity checks the limit_targets variable used to restrict how many nodes we‘ll target Limit targets can be reset by passing nil or false

Magic handler to invoke remote methods

Once the stub is created using the constructor or the RPC#rpcclient helper you can call remote actions easily:

  ret = rpc.echo(:msg => "hello world")

This will call the ‘echo’ action of the ‘rpctest’ agent and return the result as an array, the array will be a simplified result set from the usual full MCollective::Client#req with additional error codes and error text:

{

  :sender => "remote.box.com",
  :statuscode => 0,
  :statusmsg => "OK",
  :data => "hello world"

}

If :statuscode is 0 then everything went find, if it‘s 1 then you supplied the correct arguments etc but the request could not be completed, you‘ll find a human parsable reason in :statusmsg then.

Codes 2 to 5 maps directly to UnknownRPCAction, MissingRPCData, InvalidRPCData and UnknownRPCError see below for a description of those, in each case :statusmsg would be the reason for failure.

To get access to the full result of the MCollective::Client#req calls you can pass in a block:

  rpc.echo(:msg => "hello world") do |resp|
     pp resp
  end

In this case resp will the result from MCollective::Client#req. Instead of returning simple text and codes as above you‘ll also need to handle the following exceptions:

UnknownRPCAction - There is no matching action on the agent MissingRPCData - You did not supply all the needed parameters for the action InvalidRPCData - The data you did supply did not pass validation UnknownRPCError - Some other error prevented the agent from running

During calls a progress indicator will be shown of how many results we‘ve received against how many nodes were discovered, you can disable this by setting progress to false:

  rpc.progress = false

This supports a 2nd mode where it will send the SimpleRPC request and never handle the responses. It‘s a bit like UDP, it sends the request with the filter attached and you only get back the requestid, you have no indication about results.

You can invoke this using:

  puts rpc.echo(:process_results => false)

This will output just the request id.

Batched processing is supported:

  printrpc rpc.ping(:batch_size => 5)

This will do everything exactly as normal but communicate to only 5 agents at a time

Creates a suitable request hash for the SimpleRPC agent.

You‘d use this if you ever wanted to take care of sending requests on your own - perhaps via Client#sendreq if you didn‘t care for responses.

In that case you can just do:

  msg = your_rpc.new_request("some_action", :foo => :bar)
  filter = your_rpc.filter

  your_rpc.client.sendreq(msg, msg[:agent], filter)

This will send a SimpleRPC request to the action some_action with arguments :foo = :bar, it will return immediately and you will have no indication at all if the request was receieved or not

Clearly the use of this technique should be limited and done only if your code requires such a thing

Provides a normal options hash like you would get from Optionparser

Pick a number of nodes from the discovered nodes

The count should be a string that can be either just a number or a percentage like 10%

It will select nodes from the discovered list based on the rpclimitmethod configuration option which can be either :first or anything else

  - :first would be a simple way to do a distance based
    selection
  - anything else will just pick one at random
  - if random chosen, and batch-seed set, then set srand
    for the generator, and reset afterwards

process client requests by calling a block on each result in this mode we do not do anything fancy with the result objects and we raise exceptions if there are problems with the data

Handles result sets that has no block associated, sets fails and ok in the stats object and return a hash of the response to send to the caller

Resets various internal parts of the class, most importantly it clears out the cached discovery

Reet the filter to an empty one

For the provided arguments and action the input arguments get modified by supplying any defaults provided in the DDL for arguments that were not supplied in the request

We then pass the modified arguments to the DDL for validation

[Validate]