class Orchestrator::Device::MakebreakConnection

Public Instance Methods

disconnect() click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 156
def disconnect
    @connected = false
    @disconnecting = true
    close_connection(:after_writing)
end
on_close() click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 81
def on_close
    @delaying = false
    @connected = false
    @changing_state = false
    @disconnecting = false


    if @connecting
        @connecting.cancel
        @connecting = nil
    end

    # Prevent re-connect if terminated
    unless @terminated
        @retries += 1
        the_time = @processor.thread.now
        boundry = @last_retry + @config[:thrashing_threshold]

        # ensure we are not thrashing (rapid connect then disconnect)
        # This equals a disconnect and requires a warning
        if @retries == 1 && boundry >= the_time
            @retries += 1
            @manager.logger.warn('possible connection thrashing. Disconnecting')
        end

        @activity.cancel if @activity
        @activity = nil

        if @retries == 1
            if @write_queue.length > 0
                # We reconnect here as there are pending writes
                @last_retry = the_time
                reconnect
            end
        else # retries > 1
            @write_queue.clear

            variation = 1 + rand(2000)
            @connecting = @manager.get_scheduler.in(3000 + variation) do
                @connecting = nil
                reconnect
            end

            # we mark the queue as offline if more than 1 reconnect fails
            #  or if the first connect fails
            if @retries == 2 || (@retries == 3 && @last_retry == 0)
                @processor.disconnected
                @processor.queue.offline(@config[:clear_queue_on_disconnect])
            end
        end
    end
end
on_connect(transport) click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 55
def on_connect(transport)
    @connected = true
    @changing_state = false

    if @connecting
        @connecting.cancel
        @connecting = nil
    end

    if @terminated
        close_connection(:after_writing)
    else
        begin
            use_tls(@config) if @tls
        rescue => e
            @manager.logger.print_error(e, 'error starting tls')
        end

        if @config[:wait_ready]
            @delaying = ''
        else
            init_connection
        end
    end
end
on_read(data, *args) click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 134
def on_read(data, *args)
    if @delaying
        @delaying << data
        result = @delaying.split(@config[:wait_ready], 2)
        if result.length > 1
            @delaying = false
            init_connection
            rem = result[-1]
            @processor.buffer(rem) unless rem.empty?
        end
    else
        @processor.buffer(data)
    end
end
post_init(manager, processor, tls) click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 5
def post_init(manager, processor, tls)
    @manager = manager
    @processor = processor
    @config = @processor.config
    @tls = tls

    @connected = false
    @changing_state = true
    @disconnecting = false
    @last_retry = 0


    @activity = nil     # Activity timer
    @connecting = nil   # Connection timer
    @retries = 2        # Connection retries
    @write_queue = []

    @timeout = method(:timeout)
    @reset_timeout = method(:reset_timeout)
end
terminate() click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 149
def terminate
    @terminated = true
    @connecting.cancel if @connecting
    @activity.cancel if @activity
    close_connection(:after_writing) if @transport.connected
end
transmit(cmd) click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 26
def transmit(cmd)
    return if @terminated

    data = cmd[:data]

    if @connected
        promise = write(data)
        reset_timeout
        if cmd[:wait]
            promise.catch do |err|
                if @processor.queue.waiting == cmd
                    # Fail fast
                    @processor.thread.next_tick do
                        @processor.__send__(:resp_failure, err)
                    end
                else
                    cmd[:defer].reject(err)
                end
            end
        end
    elsif @retries < 2
        @write_queue << cmd
        reconnect unless @disconnecting
    else
        cmd[:defer].reject(Error::CommandFailure.new "transmit aborted as disconnected")
    end
    # discards data when officially disconnected
end

Protected Instance Methods

init_connection() click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 201
def init_connection
    # Write pending directly
    queue = @write_queue
    @write_queue = []
    while queue.length > 0
        transmit(queue.shift)
    end

    # Notify module
    if @retries > 1
        @processor.queue.online
        @processor.connected
    end
    @retries = 0

    # Start inactivity timeout
    reset_timeout
end
reconnect() click to toggle source
Calls superclass method
# File lib/orchestrator/device/transport_makebreak.rb, line 195
def reconnect
    return if @changing_state || @connected
    @changing_state = true
    super
end
reset_timeout() click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 171
def reset_timeout
    return if @terminated

    if @activity
        @activity.cancel
        @activity = nil
    end

    timeout = @config[:inactivity_timeout] || 0
    if timeout > 0
        @activity = @manager.get_scheduler.in(timeout, @timeout)
    else # Wait for until queue complete
        waiting = @processor.queue.waiting
        if waiting
            if waiting[:makebreak_set].nil?
                waiting[:defer].promise.finally @reset_timeout
                waiting[:makebreak_set] = true
            end
        elsif @processor.queue.length == 0
            disconnect
        end
    end
end
timeout(*args) click to toggle source
# File lib/orchestrator/device/transport_makebreak.rb, line 166
def timeout(*args)
    @activity = nil
    disconnect
end