Issues (393)

lib/nose/proxy.rb (1 issue)

Severity
1
# frozen_string_literal: true
2
3 1
module NoSE
4
  # Query processing proxies to transparently execute queries against a backend
5 1
  module Proxy
6
    # A proxy server to interpret our query language and implement query plans
7 1
    class ProxyBase
8 1
      attr_reader :logger
0 ignored issues
show
Add an empty line after attribute accessor.
Loading history...
9 1
      def initialize(config, result, backend)
10
        @logger = Logging.logger['nose::proxy']
11
12
        @result = result
13
        @backend = backend
14
        @config = config
15
16
        @continue = true
17
      end
18
19
      # Start the proxy server
20
      # @return [void]
21 1
      def start
22
        @logger.info "Starting server on port #{@config[:port]}"
23
24
        server_socket = TCPServer.new('127.0.0.1', @config[:port])
25
        server_socket.listen(100)
26
27
        @read_sockets = [server_socket]
28
        @write_sockets = []
29
        loop do
30
          break unless @continue && select_connection(server_socket)
31
        end
32
      end
33
34
      # @abstract Subclasses should process a new connection
35
      #           on the given socket
36
      # :nocov:
37
      # @return [void]
38 1
      def handle_connection(_socket)
39
        fail NotImplementedError
40
      end
41
      # :nocov:
42
43
      # @abstract Subclasses should dispose of state associated with the socket
44
      # :nocov:
45
      # @return [void]
46 1
      def remove_connection(_socket)
47
        fail NotImplementedError
48
      end
49
      # :nocov:
50
51
      # Stop accepting connections
52
      # @return [void]
53 1
      def stop
54
        @continue = false
55
      end
56
57 1
      private
58
59
      # Select sockets which are available to be processed
60
      # @return [void]
61 1
      def select_connection(server_socket)
62
        read, write, error = IO.select @read_sockets, @write_sockets,
63
                                       @read_sockets + @write_sockets, 5
64
        return true if read.nil?
65
66
        # Check if we have a new incoming connection
67
        if read.include? server_socket
68
          accept_connection server_socket
69
          read.delete server_socket
70
        elsif error.include? server_socket
71
          @logger.error 'Server socket died'
72
          return false
73
        end
74
75
        # Remove all sockets which have errors
76
        error.each { |socket| remove_connection socket }
77
        @read_sockets -= error
78
        @write_sockets -= error
79
80
        # Handle connections on each available socket
81
        process_connections read + write
82
      end
83
84
      # Accept the new connection
85
      # @return [void]
86 1
      def accept_connection(server_socket)
87
        client_socket, = server_socket.accept
88
        @read_sockets << client_socket
89
        @write_sockets << client_socket
90
      end
91
92
      # Process all pending connections
93
      # @return [void]
94 1
      def process_connections(sockets)
95
        sockets.each do |socket|
96
          @write_sockets.delete socket
97
          @read_sockets.delete socket unless handle_connection socket
98
        end
99
      end
100
    end
101
  end
102
end
103