<commit_before>require 'david/server/multicast'
require 'david/server/options'
require 'david/server/respond'

module David
  class Server
    include Celluloid::IO
    include CoAP::Codification

    include Multicast
    include Options
    include Respond

    attr_reader :logger, :socket

    finalizer :shutdown

    def initialize(app, options)
      @block   = choose(:block,   options[:Block])
      @cbor    = choose(:cbor,    options[:CBOR])
      @host    = choose(:host,    options[:Host])
      @logger  = choose(:logger,  options[:Log])
      @mcast   = choose(:mcast,   options[:Multicast])
      @observe = choose(:observe, options[:Observe])
      @port    = options[:Port].to_i

      @app     = app.respond_to?(:new) ? app.new : app

      logger.info "David #{David::VERSION} on #{RUBY_DESCRIPTION}"
      logger.info "Starting on [#{@host}]:#{@port}"

      @ipv6 = IPAddr.new(@host).ipv6?
      af = @ipv6 ? ::Socket::AF_INET6 : ::Socket::AF_INET

      # Actually Celluloid::IO::UDPSocket.
      @socket = UDPSocket.new(af)

      begin
        multicast_initialize if @mcast
      rescue Errno::ENODEV, Errno::EADDRNOTAVAIL
        logger.warn 'Multicast initialization failure: Device not found.'
        @mcast = false
      end

      @socket.bind(@host, @port)

      async.run
    end

    private

    def handle_input(*args)
      data, sender, _, anc = args
      host, port = sender.ip_address, sender.ip_port

      message = CoAP::Message.parse(data)
      request = Request.new(host, port, message, anc)

      return unless request.con? || request.non?
      return unless request.valid_method?
      return if !request.non? && request.multicast?

      logger.info "[#{host}]:#{port}: #{message}"
      logger.debug message.inspect

      response, options = respond(request)

      unless response.nil?
        logger.debug response.inspect
        CoAP::Ether.send(response, host, port, options.merge(socket: @socket))
      end
    end

    def run
      # loop { async.handle_input(*@socket.recvfrom(1152)) }

      loop do
        begin
          async.handle_input(*@socket.to_io.recvmsg_nonblock)
        rescue ::IO::WaitReadable
          Celluloid::IO.wait_readable(@socket)
          retry
        end
      end
    end

    def shutdown
      @socket.close unless @socket.nil?
    end
  end
end
<commit_msg>Removed old recvfrom.<commit_after>require 'david/server/multicast'
require 'david/server/options'
require 'david/server/respond'

module David
  class Server
    include Celluloid::IO
    include CoAP::Codification

    include Multicast
    include Options
    include Respond

    attr_reader :logger, :socket

    finalizer :shutdown

    def initialize(app, options)
      @block   = choose(:block,   options[:Block])
      @cbor    = choose(:cbor,    options[:CBOR])
      @host    = choose(:host,    options[:Host])
      @logger  = choose(:logger,  options[:Log])
      @mcast   = choose(:mcast,   options[:Multicast])
      @observe = choose(:observe, options[:Observe])
      @port    = options[:Port].to_i

      @app     = app.respond_to?(:new) ? app.new : app

      logger.info "David #{David::VERSION} on #{RUBY_DESCRIPTION}"
      logger.info "Starting on [#{@host}]:#{@port}"

      @ipv6 = IPAddr.new(@host).ipv6?
      af = @ipv6 ? ::Socket::AF_INET6 : ::Socket::AF_INET

      # Actually Celluloid::IO::UDPSocket.
      @socket = UDPSocket.new(af)

      begin
        multicast_initialize if @mcast
      rescue Errno::ENODEV, Errno::EADDRNOTAVAIL
        logger.warn 'Multicast initialization failure: Device not found.'
        @mcast = false
      end

      @socket.bind(@host, @port)

      async.run
    end

    private

    def handle_input(*args)
      data, sender, _, anc = args
      host, port = sender.ip_address, sender.ip_port

      message = CoAP::Message.parse(data)
      request = Request.new(host, port, message, anc)

      return unless request.con? || request.non?
      return unless request.valid_method?
      return if !request.non? && request.multicast?

      logger.info "[#{host}]:#{port}: #{message}"
      logger.debug message.inspect

      response, options = respond(request)

      unless response.nil?
        logger.debug response.inspect
        CoAP::Ether.send(response, host, port, options.merge(socket: @socket))
      end
    end

    def run
      loop do
        begin
          async.handle_input(*@socket.to_io.recvmsg_nonblock)
        rescue ::IO::WaitReadable
          Celluloid::IO.wait_readable(@socket)
          retry
        end
      end
    end

    def shutdown
      @socket.close unless @socket.nil?
    end
  end
end

{'fraction_non_alphanumeric': 0.12012012012012012, 'fraction_numerical': 0.002574002574002574, 'mean_word_length': 2.5704441041347628, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4850337', 'n_tokens_mistral': 1480, 'n_tokens_neox': 1444, 'n_words': 326}