lib/automate-em/device/device_connection.rb in automate-em-0.0.2 vs lib/automate-em/device/device_connection.rb in automate-em-0.0.3

- old
+ new

@@ -26,11 +26,14 @@ @config = { :max_buffer => 524288, # 512kb :clear_queue_on_disconnect => false, :flush_buffer_on_disconnect => false, - :priority_bonus => 20 + :priority_bonus => 20, + :inactivity_timeout => 0 # part of make and break options + # :response_length # an alternative to response_delimiter (lower priority) + # :response_delimiter # here instead of a function call } # # Queues @@ -249,33 +252,42 @@ # NOTE: The buffer cannot be defered otherwise there are concurrency issues # def do_receive_data(data) @last_recieve_at = Time.now.to_f - if @parent.respond_to?(:response_delimiter) - begin + begin + if @config[:response_delimiter].present? if @buf.nil? - del = @parent.response_delimiter + del = @config[:response_delimiter] if del.class == Array del = array_to_str(del) elsif del.class == Fixnum del = "" << del #array_to_str([del & 0xFF]) end @buf = BufferedTokenizer.new(del, @config[:max_buffer]) # Call back for character end data = @buf.extract(data) - rescue => e - @buf = nil # clear the buffer - EM.defer do # Error in a thread - AutomateEm.print_error(logger, e, { - :message => "module #{@parent.class} error whilst setting delimiter", - :level => Logger::ERROR - }) + elsif @config[:response_length].present? + (@buf ||= "") << data + data = @buf.scan(/.{1,#{@config[:response_length]}}/) + if data[-1].length == @config[:response_length] + @buf = nil + else + @buf = data[-1] + data = data[0..-2] end + else data = [data] end - else + rescue => e + @buf = nil # clear the buffer + EM.defer do # Error in a thread + AutomateEm.print_error(logger, e, { + :message => "module #{@parent.class} error whilst setting delimiter", + :level => Logger::ERROR + }) + end data = [data] end if @waiting && data.length > 0 if @processing @@ -295,11 +307,11 @@ end end # - # Caled from recieve + # Called from receive # def process_response(response, command) EM.defer do do_process_response(response, command) end @@ -436,11 +448,11 @@ end end end def process_response_complete - if (@make_break && @send_queue.empty?) || @command[:force_disconnect] + if (@make_break && @config[:inactivity_timeout] == 0 && @send_queue.empty?) || @command[:force_disconnect] if @connected close_connection_after_writing @disconnecting = true end @com_paused = true @@ -481,11 +493,11 @@ } # # Make sure we are sending appropriately formatted data # - if data.class == Array + if data.is_a?(Array) data = array_to_str(data) elsif options[:hex_string] == true data = hex_to_byte(data) end @@ -589,45 +601,48 @@ # # Connection state # - def call_connected(*args) # Called from a deferred thread + def call_connected(*args) # # NOTE:: Same as add parent in device module!!! # TODO:: Should break into a module and include it # + set_comm_inactivity_timeout(@config[:inactivity_timeout]) @task_queue.push lambda { - @parent[:connected] = true - - begin - @send_monitor.mon_synchronize { # Any sends in here are high priority (no emits as this function must return) - @parent.connected(*args) if @parent.respond_to?(:connected) - } - rescue => e - # - # save from bad user code (don't want to deplete thread pool) - # - AutomateEm.print_error(logger, e, { - :message => "module #{@parent.class} error whilst calling: connect", - :level => Logger::ERROR - }) - ensure - EM.schedule do + EM.defer do + @parent[:connected] = true + + begin + @send_monitor.mon_synchronize { # Any sends in here are high priority (no emits as this function must return) + @parent.connected(*args) if @parent.respond_to?(:connected) + } + rescue => e # - # First connect if no commands pushed then we disconnect asap + # save from bad user code (don't want to deplete thread pool) # - if @make_break && @first_connect && @send_queue.size == 0 - close_connection_after_writing - @disconnecting = true - @com_paused = true - @first_connect = false - elsif @com_paused - @com_paused = false - @wait_queue.push(nil) - else - EM.defer do - logger.info "Reconnected, communications not paused." + AutomateEm.print_error(logger, e, { + :message => "module #{@parent.class} error whilst calling: connect", + :level => Logger::ERROR + }) + ensure + EM.schedule do + # + # First connect if no commands pushed then we disconnect asap + # + if @make_break && @first_connect && @send_queue.size == 0 + close_connection_after_writing + @disconnecting = true + @com_paused = true + @first_connect = false + elsif @com_paused + @com_paused = false + @wait_queue.push(nil) + else + EM.defer do + logger.info "Reconnected, communications not paused." + end end end end end } \ No newline at end of file