Module: SDN::CLI::MQTT::Write
- Defined in:
- lib/sdn/cli/mqtt/write.rb
Overview
Writer loop that drains the outbound queue and manages retries and follow-up timing.
Instance Method Summary collapse
-
#write ⇒ void
Continuously drains the prioritized queue and transmits SDN messages.
Instance Method Details
#write ⇒ void
This method returns an undefined value.
Continuously drains the prioritized queue and transmits SDN messages.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/sdn/cli/mqtt/write.rb', line 11 def write last_write_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) loop do = nil @mutex.synchronize do # got woken up early by another command getting queued; spin while @response_pending remaining_wait = @response_pending - Process.clock_gettime(Process::CLOCK_MONOTONIC) if remaining_wait.negative? if @prior_message SDN.logger.info "Timed out waiting on response to #{@prior_message..inspect}; " \ "retries left: #{@prior_message.remaining_retries}" else SDN.logger.info "Timed out waiting on response" end @response_pending = nil @broadcast_pending = nil if @prior_message if @prior_message.remaining_retries.zero? handle_timeout_fallback(@prior_message.) elsif Message.group_address?(@prior_message..src) && !@pending_group_motors.empty? SDN.logger.debug "Re-targetting group message to individual motors" @pending_group_motors.each do |addr| = @prior_message..dup .src = [0, 0, 1] .dest = Message.parse_address(addr) @queue.push(MessageAndRetries.new(, @prior_message.remaining_retries, @prior_message.priority)) end @pending_group_motors = [] else @queue.push(@prior_message) end @prior_message = nil end else @cond.wait(@mutex, remaining_wait) end end = @queue.shift if && ( ..ack_requested || ..class.name =~ /^SDN::Message::Get/) @response_pending = Process.clock_gettime(Process::CLOCK_MONOTONIC) + WAIT_TIME @pending_group_motors = if Message.group_address?(..src) group_addr = Message.print_address(..src).delete( "." ) @groups[group_addr]&.motor_objects&.map(&:addr) || [] else [] end if ..dest == BROADCAST_ADDRESS || ( Message.group_address?(..src) && ..is_a?(Message::GetNodeAddr)) @broadcast_pending = Process.clock_gettime(Process::CLOCK_MONOTONIC) + BROADCAST_WAIT end end # wait until there is a message if @response_pending .remaining_retries -= 1 @prior_message = elsif @prior_message = nil elsif @auto_discover && @motors_found = MessageAndRetries.new(Message::GetNodeAddr.new, 1, 50) @motors_found = false # nothing pending to write, and motors found on the last iteration; # look for more motors else @cond.wait(@mutex) end end next unless = . # minimum time between messages now = Process.clock_gettime(Process::CLOCK_MONOTONIC) sleep_time = 0.1 - (now - last_write_at) sleep(sleep_time) if sleep_time.positive? @sdn.send() last_write_at = now end rescue => e SDN.logger.fatal "Failure writing: #{e}: #{e.backtrace}" exit 1 end |