Module: DatTCP::Server

Defined in:
lib/dat-tcp.rb

Defined Under Namespace

Classes: State

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



15
16
17
# File 'lib/dat-tcp.rb', line 15

def logger
  @logger
end

Instance Method Details

#client_file_descriptorsObject



107
108
109
# File 'lib/dat-tcp.rb', line 107

def client_file_descriptors
  @worker_pool ? @worker_pool.connections.map(&:fileno) : []
end

#configure_tcp_server(tcp_server) ⇒ Object



128
129
# File 'lib/dat-tcp.rb', line 128

def configure_tcp_server(tcp_server)
end

#file_descriptorObject



103
104
105
# File 'lib/dat-tcp.rb', line 103

def file_descriptor
  @tcp_server.fileno if self.listening?
end

#halt(wait = true) ⇒ Object



84
85
86
87
88
# File 'lib/dat-tcp.rb', line 84

def halt(wait = true)
  set_state :halt
  run_hook 'on_halt'
  wait_for_shutdown if wait
end

#initialize(config = nil) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/dat-tcp.rb', line 17

def initialize(config = nil)
  config = OpenStruct.new(config || {})
  @backlog_size     = config.backlog_size     || 1024
  @debug            = config.debug            || false
  @min_workers      = config.min_workers      || 2
  @max_workers      = config.max_workers      || 4
  @ready_timeout    = config.ready_timeout    || 1
  @shutdown_timeout = config.shutdown_timeout || 15

  @logger = DatTCP::Logger.new(@debug)

  check_configuration

  @tcp_server       = nil
  @work_loop_thread = nil
  @worker_pool      = nil
  set_state :stop
end

#inspectObject



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/dat-tcp.rb', line 143

def inspect
  reference = '0x0%x' % (self.object_id << 1)
  "#<#{self.class}:#{reference}".tap do |inspect_str|
    inspect_str << " @state=#{@state.inspect}"
    if self.listening?
      port, ip = @tcp_server.addr[1, 2]
      inspect_str << " @ip=#{ip.inspect} @port=#{port.inspect}"
    end
    inspect_str << " @work_loop_status=#{@work_loop_thread.status.inspect}" if self.running?
    inspect_str << ">"
  end
end

#ipObject



95
96
97
# File 'lib/dat-tcp.rb', line 95

def ip
  @tcp_server.addr[2] if self.listening?
end

#listen(*args) ⇒ Object

Socket Options:

  • SOL_SOCKET - specifies the protocol layer the option applies to.

    SOL_SOCKET is basic socket options (as opposed to
    something like IPPROTO_TCP for TCP socket options).
    
  • SO_REUSEADDR - indicates that the rules used in validating addresses

    supplied in a bind(2) call should allow reuse of local
    addresses. This will allow us to re-bind to a port if we
    were shutdown and started right away. This will still
    throw an "address in use" if a socket is active on the
    port.
    


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dat-tcp.rb', line 47

def listen(*args)
  build_server_method = if args.size == 2
    :new
  elsif args.size == 1
    :for_fd
  else
    raise InvalidListenArgsError.new
  end
  set_state :listen
  run_hook 'on_listen'
  @tcp_server = TCPServer.send(build_server_method, *args)

  @tcp_server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
  run_hook 'configure_tcp_server', @tcp_server

  @tcp_server.listen(@backlog_size)
end

#listening?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/dat-tcp.rb', line 111

def listening?
  !!@tcp_server
end

#on_haltObject



140
141
# File 'lib/dat-tcp.rb', line 140

def on_halt
end

#on_listenObject

Hooks



125
126
# File 'lib/dat-tcp.rb', line 125

def on_listen
end

#on_pauseObject



134
135
# File 'lib/dat-tcp.rb', line 134

def on_pause
end

#on_runObject



131
132
# File 'lib/dat-tcp.rb', line 131

def on_run
end

#on_stopObject



137
138
# File 'lib/dat-tcp.rb', line 137

def on_stop
end

#pause(wait = true) ⇒ Object



72
73
74
75
76
# File 'lib/dat-tcp.rb', line 72

def pause(wait = true)
  set_state :pause
  run_hook 'on_pause'
  wait_for_shutdown if wait
end

#portObject



99
100
101
# File 'lib/dat-tcp.rb', line 99

def port
  @tcp_server.addr[1] if self.listening?
end

#run(client_file_descriptors = nil) ⇒ Object

Raises:



65
66
67
68
69
70
# File 'lib/dat-tcp.rb', line 65

def run(client_file_descriptors = nil)
  raise NotListeningError.new if !self.listening?
  set_state :run
  run_hook 'on_run'
  @work_loop_thread = Thread.new{ work_loop(client_file_descriptors) }
end

#running?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/dat-tcp.rb', line 115

def running?
  !!@work_loop_thread
end

#serve(socket) ⇒ Object

This method should be overwritten to handle new connections



120
121
# File 'lib/dat-tcp.rb', line 120

def serve(socket)
end

#stop(wait = true) ⇒ Object



78
79
80
81
82
# File 'lib/dat-tcp.rb', line 78

def stop(wait = true)
  set_state :stop
  run_hook 'on_stop'
  wait_for_shutdown if wait
end

#stop_listeningObject



90
91
92
93
# File 'lib/dat-tcp.rb', line 90

def stop_listening
  @tcp_server.close rescue false
  @tcp_server = nil
end