Class: Roby::Interface::V1::Async::Log
- Extended by:
- Logger::Hierarchy
- Includes:
- Hooks, Hooks::InstanceHooks
- Defined in:
- lib/roby/interface/v1/async/log.rb
Overview
Asynchronous access to the log stream
Roby logs are purely incremental information, which means that on connection one must process the whole existing log before being able to provide the current state. From a user perspective, this init phase is really overhead, so it’s better to avoid updating the UI while the data is being processed. For this reason, the class provides #on_init_progress and #on_init_done to provide progress information to the user, and start normal processing when init is finished.
It must be integrated into your application’s event loop by calling #poll.
Constant Summary collapse
- DEFAULT_HOST =
"localhost"
- DEFAULT_PORT =
Roby::DRoby::Logfile::Server::DEFAULT_PORT
- STATE_DISCONNECTED =
:disconnected
- STATE_CONNECTED =
:connected
- STATE_PENDING_DATA =
:pending_data
Instance Attribute Summary collapse
-
#client ⇒ Roby::DRoby::Logfile::Client?
readonly
The object used to communicate to the server, or nil if we have not managed to connect yet.
-
#connection_future ⇒ Object
readonly
The future used to connect to the remote process without blocking the main event loop.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#plan_rebuilder ⇒ Roby::DRoby::PlanRebuilder
readonly
The plan rebuilder object, which processes the log stream to rebuild #plan.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
Hooks collapse
-
#on_init_done ⇒ void
Hooks called when we finished processing the initial set of data.
- #on_init_progress {|rx, init_size| ... } ⇒ void
-
#on_reachable ⇒ void
Hooks called when we successfully connected.
-
#on_unreachable ⇒ void
Hooks called when we got disconnected.
-
#on_update {|cycle_index, cycle_time| ... } ⇒ void
Hooks called when the plan rebuilder processed an update.
Instance Method Summary collapse
-
#attempt_connection ⇒ Object
Start a connection attempt.
- #clear_integrated ⇒ Object
- #close ⇒ Object
- #closed? ⇒ Boolean
- #connected? ⇒ Boolean
- #cycle_index ⇒ Object
- #cycle_start_time ⇒ Object
-
#default_plan_rebuilder ⇒ Object
private
Create a plan rebuilder for use in the async object.
- #init_done? ⇒ Boolean
-
#initialize(host = DEFAULT_REMOTE_NAME, port: DEFAULT_PORT, connect: true, plan_rebuilder: default_plan_rebuilder) ⇒ Log
constructor
A new instance of Log.
-
#plan ⇒ Roby::Plan
The plan self is working on.
-
#poll(max: 0.1) ⇒ (Boolean,Boolean)
Active part of the async.
-
#poll_connection_attempt ⇒ Object
Verify the state of the last connection attempt.
-
#reachable? ⇒ Boolean
True if we are connected to a client.
-
#scheduler_state ⇒ Schedulers::State
Information about the scheduler state.
- #unreachable! ⇒ Object
Methods included from Hooks
Constructor Details
#initialize(host = DEFAULT_REMOTE_NAME, port: DEFAULT_PORT, connect: true, plan_rebuilder: default_plan_rebuilder) ⇒ Log
Returns a new instance of Log.
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/roby/interface/v1/async/log.rb', line 94 def initialize(host = DEFAULT_REMOTE_NAME, port: DEFAULT_PORT, connect: true, plan_rebuilder: default_plan_rebuilder) @host = host @port = port @plan_rebuilder = plan_rebuilder @first_connection_attempt = true @closed = false if connect attempt_connection end end |
Instance Attribute Details
#client ⇒ Roby::DRoby::Logfile::Client? (readonly)
Returns the object used to communicate to the server, or nil if we have not managed to connect yet.
79 80 81 |
# File 'lib/roby/interface/v1/async/log.rb', line 79 def client @client end |
#connection_future ⇒ Object (readonly)
The future used to connect to the remote process without blocking the main event loop
82 83 84 |
# File 'lib/roby/interface/v1/async/log.rb', line 82 def connection_future @connection_future end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
76 77 78 |
# File 'lib/roby/interface/v1/async/log.rb', line 76 def host @host end |
#plan_rebuilder ⇒ Roby::DRoby::PlanRebuilder (readonly)
The plan rebuilder object, which processes the log stream to rebuild #plan
31 32 33 |
# File 'lib/roby/interface/v1/async/log.rb', line 31 def plan_rebuilder @plan_rebuilder end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
76 77 78 |
# File 'lib/roby/interface/v1/async/log.rb', line 76 def port @port end |
Instance Method Details
#attempt_connection ⇒ Object
Start a connection attempt
111 112 113 114 115 116 |
# File 'lib/roby/interface/v1/async/log.rb', line 111 def attempt_connection @connection_future = Concurrent::Future.new do Roby::DRoby::Logfile::Client.new(host, port) end connection_future.execute end |
#clear_integrated ⇒ Object
237 238 239 |
# File 'lib/roby/interface/v1/async/log.rb', line 237 def clear_integrated plan_rebuilder.clear_integrated end |
#close ⇒ Object
170 171 172 173 174 |
# File 'lib/roby/interface/v1/async/log.rb', line 170 def close @closed = true unreachable! plan_rebuilder.clear end |
#closed? ⇒ Boolean
166 167 168 |
# File 'lib/roby/interface/v1/async/log.rb', line 166 def closed? !!@closed end |
#connected? ⇒ Boolean
106 107 108 |
# File 'lib/roby/interface/v1/async/log.rb', line 106 def connected? !!client end |
#cycle_index ⇒ Object
181 182 183 |
# File 'lib/roby/interface/v1/async/log.rb', line 181 def cycle_index plan_rebuilder&.cycle_index end |
#cycle_start_time ⇒ Object
185 186 187 |
# File 'lib/roby/interface/v1/async/log.rb', line 185 def cycle_start_time plan_rebuilder&.cycle_start_time end |
#default_plan_rebuilder ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create a plan rebuilder for use in the async object
90 91 92 |
# File 'lib/roby/interface/v1/async/log.rb', line 90 def default_plan_rebuilder DRoby::PlanRebuilder.new end |
#init_done? ⇒ Boolean
189 190 191 |
# File 'lib/roby/interface/v1/async/log.rb', line 189 def init_done? client&.init_done? end |
#on_init_done ⇒ void
This method returns an undefined value.
Hooks called when we finished processing the initial set of data
65 |
# File 'lib/roby/interface/v1/async/log.rb', line 65 define_hooks :on_init_done |
#on_init_progress {|rx, init_size| ... } ⇒ void
This method returns an undefined value.
62 |
# File 'lib/roby/interface/v1/async/log.rb', line 62 define_hooks :on_init_progress |
#on_reachable ⇒ void
This method returns an undefined value.
Hooks called when we successfully connected
55 |
# File 'lib/roby/interface/v1/async/log.rb', line 55 define_hooks :on_reachable |
#on_unreachable ⇒ void
This method returns an undefined value.
Hooks called when we got disconnected
59 |
# File 'lib/roby/interface/v1/async/log.rb', line 59 define_hooks :on_unreachable |
#on_update {|cycle_index, cycle_time| ... } ⇒ void
This method returns an undefined value.
Hooks called when the plan rebuilder processed an update
72 |
# File 'lib/roby/interface/v1/async/log.rb', line 72 define_hooks :on_update |
#plan ⇒ Roby::Plan
The plan self is working on
36 37 38 |
# File 'lib/roby/interface/v1/async/log.rb', line 36 def plan plan_rebuilder.plan end |
#poll(max: 0.1) ⇒ (Boolean,Boolean)
Active part of the async. This has to be called regularly within the system’s main event loop (e.g. Roby’s, Vizkit’s or Qt’s)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/roby/interface/v1/async/log.rb', line 127 def poll(max: 0.1) if connected? if client.read_and_process_pending(max: max) STATE_PENDING_DATA else STATE_CONNECTED end elsif !closed? poll_connection_attempt STATE_DISCONNECTED end rescue Interrupt close raise rescue ComError Log.info "link closed, trying to reconnect" unreachable! unless closed? attempt_connection end false rescue Exception => e Log.warn "error while polling connection, trying to reconnect" Roby.log_exception_with_backtrace(e, Log, :warn) unreachable! unless closed? attempt_connection end false end |
#poll_connection_attempt ⇒ Object
Verify the state of the last connection attempt
It checks on the last connection attempt, and sets #client if it was successful, as well as call the callbacks registered with #on_reachable
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/roby/interface/v1/async/log.rb', line 198 def poll_connection_attempt return if client return if closed? if connection_future.complete? case e = connection_future.reason when ConnectionError, ComError Interface.info "Async::Log failed connection attempt: #{e}" attempt_connection if @first_connection_attempt @first_connection_attempt = false run_hook :on_unreachable end nil when NilClass Interface.info "successfully connected" @client = connection_future.value plan_rebuilder.clear run_hook :on_reachable client.on_init_progress do |received, expected| run_hook :on_init_progress, received, expected end client.on_init_done do run_hook :on_init_done end client.on_data do |data| plan_rebuilder.process_one_cycle(data) cycle = plan_rebuilder.cycle_index time = plan_rebuilder.cycle_start_time Interface.debug "Async update(#{cycle}, #{time})" run_hook :on_update, cycle, time end else raise connection_future.reason end end end |
#reachable? ⇒ Boolean
True if we are connected to a client
177 178 179 |
# File 'lib/roby/interface/v1/async/log.rb', line 177 def reachable? !!client end |
#scheduler_state ⇒ Schedulers::State
Information about the scheduler state
43 44 45 |
# File 'lib/roby/interface/v1/async/log.rb', line 43 def scheduler_state plan.consolidated_scheduler_state end |
#unreachable! ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/roby/interface/v1/async/log.rb', line 158 def unreachable! if client client.close unless client.closed? @client = nil run_hook :on_unreachable end end |