Class: RightScale::RouterClient

Inherits:
BaseRetryClient show all
Defined in:
lib/right_agent/clients/router_client.rb

Overview

HTTP interface to RightNet router

Constant Summary collapse

API_VERSION =

RightNet router API version for use in X-API-Version header

"2.0"
CONNECT_INTERVAL =

Initial interval between attempts to make a WebSocket connection

30
MAX_CONNECT_INTERVAL =

Maximum interval between attempts to make a WebSocket connection

60 * 60 * 24
RECONNECT_INTERVAL =

Initial interval between attempts to reconnect or long-poll when router is not responding

2
MAX_RECONNECT_INTERVAL =

Maximum interval between attempts to reconnect or long-poll when router is not responding

30
CHECK_INTERVAL =

Interval between checks for lost WebSocket connection

5
BACKOFF_FACTOR =

Backoff factor for connect and reconnect intervals

2
NORMAL_CLOSE =

WebSocket close status codes

1000
SHUTDOWN_CLOSE =
1001
PROTOCOL_ERROR_CLOSE =
1002
UNEXPECTED_ERROR_CLOSE =
1011
DEFAULT_LISTEN_TIMEOUT =

Default time to wait for an event or to ping WebSocket

60
MAX_LISTEN_FAILURES =

Maximum repeated listen failures at which point give up listening

10

Constants inherited from BaseRetryClient

BaseRetryClient::DEFAULT_OPEN_TIMEOUT, BaseRetryClient::DEFAULT_RECONNECT_INTERVAL, BaseRetryClient::DEFAULT_REQUEST_TIMEOUT, BaseRetryClient::DEFAULT_RETRY_INTERVALS, BaseRetryClient::DEFAULT_RETRY_TIMEOUT, BaseRetryClient::PERMITTED_STATE_TRANSITIONS

Instance Attribute Summary

Attributes inherited from BaseRetryClient

#state

Instance Method Summary collapse

Methods inherited from BaseRetryClient

#communicated, #init, #status

Constructor Details

#initialize(auth_client, options) ⇒ RouterClient

Create RightNet router client

Options Hash (options):

  • :open_timeout (Numeric)

    maximum wait for connection; defaults to DEFAULT_OPEN_TIMEOUT

  • :request_timeout (Numeric)

    maximum wait for response; defaults to DEFAULT_REQUEST_TIMEOUT

  • :listen_timeout (Numeric)

    maximum wait for event; defaults to DEFAULT_LISTEN_TIMEOUT

  • :long_polling_only (Boolean)

    never attempt to create a WebSocket, always long-polling instead

  • :retry_timeout (Numeric)

    maximum before stop retrying; defaults to DEFAULT_RETRY_TIMEOUT

  • :retry_intervals (Array)

    between successive retries; defaults to DEFAULT_RETRY_INTERVALS

  • :retry_enabled (Boolean)

    for requests that fail to connect or that return a retry result

  • :reconnect_interval (Numeric)

    for reconnect attempts after lose connectivity

  • :non_blocking (Boolean)

    i/o is to be used for HTTP requests by applying EM::HttpRequest and fibers instead of RestClient; requests remain synchronous

  • :filter_params (Array)

    symbols or strings for names of request parameters whose values are to be hidden when logging; also applied to contents of any parameters named :payload

Raises:

  • (ArgumentError)

    auth client does not support this client type



95
96
97
98
# File 'lib/right_agent/clients/router_client.rb', line 95

def initialize(auth_client, options)
  init(:router, auth_client, options.merge(:server_name => "RightNet", :api_version => API_VERSION))
  @options[:listen_timeout] ||= DEFAULT_LISTEN_TIMEOUT
end

Instance Method Details

#close(scope = :all) ⇒ TrueClass

Take any actions necessary to quiesce client interaction in preparation for agent termination but allow any active requests to complete



250
251
252
253
254
# File 'lib/right_agent/clients/router_client.rb', line 250

def close(scope = :all)
  super
  update_listen_state(:cancel)
  @websocket.close(SHUTDOWN_CLOSE, "Agent terminating") if @websocket
end

#listen(routing_keys) {|event| ... } ⇒ TrueClass

Receive events via an HTTP WebSocket if available, otherwise via an HTTP long-polling

Yields:

  • (event)

    required block called each time event received

Yield Parameters:

  • event (Hash)

    received

Raises:



229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/right_agent/clients/router_client.rb', line 229

def listen(routing_keys, &handler)
  raise ArgumentError, "Block missing" unless block_given?

  @event_uuids = nil
  @listen_interval = 0
  @listen_state = :choose
  @listen_failures = 0
  @connect_interval = CONNECT_INTERVAL
  @reconnect_interval = RECONNECT_INTERVAL

  listen_loop(routing_keys, &handler)
  true
end

#notify(event, routing_keys) ⇒ TrueClass

Route event Use WebSocket if possible Do not block this request even if in the process of closing since used for request responses

Raises:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/right_agent/clients/router_client.rb', line 197

def notify(event, routing_keys)
  event[:uuid] ||= RightSupport::Data::UUID.generate
  event[:version] ||= AgentConfig.protocol_version
  params = {:event => event}
  params[:routing_keys] = routing_keys if routing_keys
  if @websocket
    path = event[:path] ? " #{event[:path]}" : ""
    to = routing_keys ? " to #{routing_keys.inspect}" : ""
    Log.info("Sending EVENT <#{event[:uuid]}> #{event[:type]}#{path}#{to}")
    @websocket.send(JSON.dump(params))
  else
    make_request(:post, "/notify", params, "notify", :request_uuid => event[:uuid], :filter_params => ["event"])
  end
  true
end

#push(type, payload, target, options = {}) ⇒ NilClass

Route a request to a single target or multiple targets with no response expected Persist the request en route to reduce the chance of it being lost at the expense of some additional network overhead Enqueue the request if the target is not currently available Never automatically retry the request if there is the possibility of it being duplicated Set time-to-live to be forever

Options Hash (options):

  • :request_uuid (String)

    uniquely identifying this request; defaults to randomly generated

  • :time_to_live (Numeric)

    seconds before request expires and is to be ignored; non-positive value or nil means never expire

Raises:



134
135
136
137
138
139
140
# File 'lib/right_agent/clients/router_client.rb', line 134

def push(type, payload, target, options = {})
  params = {
    :type => type,
    :payload => payload,
    :target => target }
  make_request(:post, "/push", params, type.split("/")[2], options)
end

#request(type, payload, target, options = {}) ⇒ Result, NilClass

Route a request to a single target with a response expected Automatically retry the request if a response is not received in a reasonable amount of time or if there is a non-delivery response indicating the target is not currently available Timeout the request if a response is not received in time, typically configured to 30 sec Because of retries there is the possibility of duplicated requests, and these are detected and discarded automatically for non-idempotent actions Allow the request to expire per the agent’s configured time-to-live, typically 1 minute

Options Hash (options):

  • :request_uuid (String)

    uniquely identifying this request; defaults to randomly generated

  • :time_to_live (Numeric)

    seconds before request expires and is to be ignored; non-positive value or nil means never expire

Raises:



173
174
175
176
177
178
179
# File 'lib/right_agent/clients/router_client.rb', line 173

def request(type, payload, target, options = {})
  params = {
    :type => type,
    :payload => payload,
    :target => target }
  make_request(:post, "/request", params, type.split("/")[2], options)
end

#stats(reset = false) ⇒ Hash

Current statistics for this client



265
266
267
268
269
270
# File 'lib/right_agent/clients/router_client.rb', line 265

def stats(reset = false)
  events = @stats["events"].all
  stats = super(reset)
  stats["events"] = events
  stats
end