class Roby::Interface::Async::Log

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}.

Constants

DEFAULT_HOST
DEFAULT_PORT
STATE_CONNECTED
STATE_DISCONNECTED
STATE_PENDING_DATA

Attributes

client[R]

@return [Roby::DRoby::Logfile::Client,nil] the object used to communicate

to the server, or nil if we have not managed to connect yet
connection_future[R]

The future used to connect to the remote process without blocking the main event loop

host[R]

@!endgroup

plan_rebuilder[R]

The plan rebuilder object, which processes the log stream to rebuild {#plan}

@return [Roby::DRoby::PlanRebuilder]

port[R]

Public Class Methods

new(host = DEFAULT_REMOTE_NAME, port: DEFAULT_PORT, connect: true, plan_rebuilder: default_plan_rebuilder) click to toggle source
# File lib/roby/interface/async/log.rb, line 88
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

Public Instance Methods

attempt_connection() click to toggle source

Start a connection attempt

# File lib/roby/interface/async/log.rb, line 105
def attempt_connection
    @connection_future = Concurrent::Future.new do
        Roby::DRoby::Logfile::Client.new(host, port)
    end
    connection_future.execute
end
clear_integrated() click to toggle source
# File lib/roby/interface/async/log.rb, line 231
def clear_integrated
    plan_rebuilder.clear_integrated
end
close() click to toggle source
# File lib/roby/interface/async/log.rb, line 164
def close
    @closed = true
    unreachable!
    plan_rebuilder.clear
end
closed?() click to toggle source
# File lib/roby/interface/async/log.rb, line 160
def closed?
    !!@closed
end
connected?() click to toggle source
# File lib/roby/interface/async/log.rb, line 100
def connected?
    !!client
end
cycle_index() click to toggle source
# File lib/roby/interface/async/log.rb, line 175
def cycle_index
    plan_rebuilder && plan_rebuilder.cycle_index
end
cycle_start_time() click to toggle source
# File lib/roby/interface/async/log.rb, line 179
def cycle_start_time
    plan_rebuilder && plan_rebuilder.cycle_start_time
end
default_plan_rebuilder() click to toggle source

@api private

Create a plan rebuilder for use in the async object

# File lib/roby/interface/async/log.rb, line 84
def default_plan_rebuilder
    DRoby::PlanRebuilder.new
end
init_done?() click to toggle source
# File lib/roby/interface/async/log.rb, line 183
def init_done?
    client && client.init_done?
end
plan() click to toggle source

The plan self is working on

@return [Roby::Plan]

# File lib/roby/interface/async/log.rb, line 33
def plan; plan_rebuilder.plan end
poll(max: 0.1) click to toggle source

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)

@return [(Boolean,Boolean)] true if we are connected to the remote server

and false otherwise
# File lib/roby/interface/async/log.rb, line 121
def poll(max: 0.1)
    if connected?
        if client.read_and_process_pending(max: max)
            return STATE_PENDING_DATA
        else return STATE_CONNECTED
        end
    elsif !closed?
        poll_connection_attempt
        return STATE_DISCONNECTED
    end
rescue Interrupt
    close
    raise

rescue ComError
    Log.info "link closed, trying to reconnect"
    unreachable!
    if !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!
    if !closed?
        attempt_connection
    end
    false
end
poll_connection_attempt() click to toggle source

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}

# File lib/roby/interface/async/log.rb, line 192
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?() click to toggle source

True if we are connected to a client

# File lib/roby/interface/async/log.rb, line 171
def reachable?
    !!client
end
scheduler_state() click to toggle source

Information about the scheduler state

@return [Schedulers::State]

# File lib/roby/interface/async/log.rb, line 38
def scheduler_state; plan.consolidated_scheduler_state end
unreachable!() click to toggle source
# File lib/roby/interface/async/log.rb, line 152
def unreachable!
    if client
        client.close if !client.closed?
        @client = nil
        run_hook :on_unreachable
    end
end