def run(host: nil, port: DEFAULT_PORT, &block)
      logger.info "Listening on port #{port}"

      Socket.udp_server_loop host, port do |msg, sender|
        logger.debug { "#{sender.remote_address.inspect} -> '#{msg.inspect}'" }
        handler = @handlers.find { |h| h.handles? msg } || next
        @state_lock.synchronize do
          handle(handler, msg, sender, &block)
        end
      end
      nil
    end
def run(host: nil, port: DEFAULT_PORT, &block)
      logger.info "Listening on port #{port}"

      Socket.udp_server_loop host, port do |msg, sender|
        logger.debug { "#{sender.remote_address.inspect} -> '#{msg.inspect}'" }
        handler = @handlers.find { |h| h.handles? msg } || next
        @state_lock.synchronize do
          handle(handler, msg, sender, &block)
        end
      end
      nil
    end
@param  password [String] the plain text password to use when validating
   new clients.
 @param  logger [Logger] the logger to use.
 Starts a new UDP server that listens on the given port. The state is
 updated atomically and yielded to an optional block everytime a change is
 made. By returning `false` the block can cancel the state update. This
 call is blocking.

 @yield [Integer] the updated state.
 @yield [Integer] the old state.

 @param  host [String] the host to listen on.
 @param  port [Integer] the UDP port to listen on.
 @return [nil]