Class: RightScale::OfflineHandler
- Defined in:
- lib/right_agent/offline_handler.rb
Overview
Handler for queueing of requests when offline relative to RightNet and then sending the requests when successfully reconnect
Constant Summary collapse
- MAX_QUEUE_FLUSH_DELAY =
Maximum seconds to wait before starting flushing offline queue when disabling offline mode
60
- MAX_QUEUED_REQUESTS =
Maximum number of offline queued requests before triggering restart vote
100
- RESTART_VOTE_DELAY =
Number of seconds that should be spent in offline mode before triggering a restart vote
15 * 60
Instance Attribute Summary collapse
-
#mode ⇒ Object
readonly
(Symbol) Current offline handling mode with possible values: Value Description :initializing Agent still initializing :online Agent connected :offline Agent disconnected.
-
#queue ⇒ Object
(Array) Offline queue.
-
#state ⇒ Object
readonly
(Symbol) Current queue state with possible values: Value Description Action Next state :created Queue created init :initializing :initializing Agent still initializing start :running :running Queue has been started disable when offline :flushing :flushing Sending queued requests enable :running :terminating Agent terminating.
Instance Method Summary collapse
-
#disable ⇒ Object
Switch back to sending requests after in-memory queue gets flushed Idempotent.
-
#enable ⇒ Object
Switch to offline mode In this mode requests are queued in memory rather than being sent Idempotent.
-
#init ⇒ Object
Initialize the offline queue All requests sent prior to running this initialization are queued and then are sent once this initialization has run All requests following this call and prior to calling start are prepended to the request queue.
-
#initialize(restart_callback, offline_stats) ⇒ OfflineHandler
constructor
Create offline queueing handler.
-
#offline? ⇒ Boolean
Is agent currently offline?.
-
#queue_request(kind, type, payload, target, token, expires_at, &callback) ⇒ Object
Queue given request in memory.
-
#queueing? ⇒ Boolean
In request queueing mode?.
-
#start ⇒ Object
Switch to online mode and send all buffered messages.
-
#terminate ⇒ Object
Prepare for agent termination.
Constructor Details
#initialize(restart_callback, offline_stats) ⇒ OfflineHandler
Create offline queueing handler
Parameters
- restart_callback(Proc)
-
Callback that is activated on each restart vote with votes being initiated
by offline queue exceeding MAX_QUEUED_REQUESTS
- offline_stats(RightSupport::Stats::Activity)
-
Offline queue tracking statistics
63 64 65 66 67 68 69 70 71 |
# File 'lib/right_agent/offline_handler.rb', line 63 def initialize(restart_callback, offline_stats) @restart_vote = restart_callback @restart_vote_timer = nil @restart_vote_count = 0 @offline_stats = offline_stats @state = :created @mode = :initializing @queue = [] end |
Instance Attribute Details
#mode ⇒ Object (readonly)
(Symbol) Current offline handling mode with possible values:
Value Description
:initializing Agent still initializing
:online Agent connected
:offline Agent disconnected
52 53 54 |
# File 'lib/right_agent/offline_handler.rb', line 52 def mode @mode end |
#queue ⇒ Object
(Array) Offline queue
55 56 57 |
# File 'lib/right_agent/offline_handler.rb', line 55 def queue @queue end |
#state ⇒ Object (readonly)
(Symbol) Current queue state with possible values:
Value Description Action Next state
:created Queue created init :initializing
:initializing Agent still initializing start :running
:running Queue has been started disable when offline :flushing
:flushing Sending queued requests enable :running
:terminating Agent terminating
45 46 47 |
# File 'lib/right_agent/offline_handler.rb', line 45 def state @state end |
Instance Method Details
#disable ⇒ Object
Switch back to sending requests after in-memory queue gets flushed Idempotent
Return
- true
-
Always return true
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/right_agent/offline_handler.rb', line 149 def disable if offline? && @state != :created Log.info("[offline] Connection to RightNet re-established") @offline_stats.finish cancel_timer @state = :flushing # Wait a bit to avoid flooding RightNet EM.add_timer(rand(MAX_QUEUE_FLUSH_DELAY)) { flush } end true end |
#enable ⇒ Object
Switch to offline mode In this mode requests are queued in memory rather than being sent Idempotent
Return
- true
-
Always return true
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/right_agent/offline_handler.rb', line 125 def enable if offline? if @state == :flushing # If we were in offline mode then switched back to online but are still in the # process of flushing the in-memory queue and are now switching to offline mode # again then stop the flushing @state = :running end else Log.info("[offline] Disconnect from RightNet detected, entering offline mode") Log.info("[offline] Messages will be queued in memory until RightNet connection is re-established") @offline_stats.update @queue ||= [] # Ensure queue is valid without losing any messages when going offline @mode = :offline start_timer end true end |
#init ⇒ Object
Initialize the offline queue All requests sent prior to running this initialization are queued and then are sent once this initialization has run All requests following this call and prior to calling start are prepended to the request queue
Return
- true
-
Always return true
81 82 83 84 |
# File 'lib/right_agent/offline_handler.rb', line 81 def init @state = :initializing if @state == :created true end |
#offline? ⇒ Boolean
Is agent currently offline?
Return
- (Boolean)
-
true if agent offline, otherwise false
107 108 109 |
# File 'lib/right_agent/offline_handler.rb', line 107 def offline? @mode == :offline || @state == :created end |
#queue_request(kind, type, payload, target, token, expires_at, &callback) ⇒ Object
Queue given request in memory
Parameters
- kind(Symbol)
-
Kind of request: :send_push or :send_request
- type(String)
-
Dispatch route for the request; typically identifies actor and action
- payload(Object)
-
Data to be sent with marshalling en route
- target(Hash|NilClass)
-
Target for request
- token(String)
-
Token uniquely identifying request
- expires_at(Integer)
-
Time in seconds in Unix-epoch when this request expires and
is to be ignored by the receiver; value 0 means never expire
Block
Optional block used to process response asynchronously with the following parameter:
result(Result):: Response with an OperationResult of SUCCESS, RETRY, NON_DELIVERY, or ERROR
Return
- true
-
Always return true
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/right_agent/offline_handler.rb', line 178 def queue_request(kind, type, payload, target, token, expires_at, &callback) request = {:kind => kind, :type => type, :payload => payload, :target => target, :token => token, :expires_at => expires_at, :callback => callback} Log.info("[offline] Queuing request: #{request.inspect}") vote_to_restart if (@restart_vote_count += 1) >= MAX_QUEUED_REQUESTS if @state == :initializing # We are in the initialization callback, requests should be put at the head of the queue @queue.unshift(request) else @queue << request end true end |
#queueing? ⇒ Boolean
In request queueing mode?
Return
- (Boolean)
-
true if should queue request, otherwise false
115 116 117 |
# File 'lib/right_agent/offline_handler.rb', line 115 def queueing? offline? && @state != :flushing end |
#start ⇒ Object
Switch to online mode and send all buffered messages
Return
- true
-
Always return true
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/right_agent/offline_handler.rb', line 90 def start if @state == :initializing if @mode == :offline @state = :running else @state = :flushing flush end @mode = :online if @mode == :initializing end true end |
#terminate ⇒ Object
Prepare for agent termination
Return
- true
-
Always return true
196 197 198 199 200 |
# File 'lib/right_agent/offline_handler.rb', line 196 def terminate @state = :terminating cancel_timer true end |