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.



13
14
15
# File 'lib/dat-tcp.rb', line 13

def logger
  @logger
end

Instance Method Details

#client_file_descriptorsObject



105
106
107
# File 'lib/dat-tcp.rb', line 105

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

#configure_tcp_server(tcp_server) ⇒ Object



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

def configure_tcp_server(tcp_server)
end

#file_descriptorObject



101
102
103
# File 'lib/dat-tcp.rb', line 101

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

#halt(wait = true) ⇒ Object



82
83
84
85
86
# File 'lib/dat-tcp.rb', line 82

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

#initialize(config = nil) ⇒ Object



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

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



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/dat-tcp.rb', line 147

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



93
94
95
# File 'lib/dat-tcp.rb', line 93

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.
    


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

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)


109
110
111
# File 'lib/dat-tcp.rb', line 109

def listening?
  !!@tcp_server
end

#on_haltObject



144
145
# File 'lib/dat-tcp.rb', line 144

def on_halt
end

#on_listenObject

Hooks



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

def on_listen
end

#on_pauseObject



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

def on_pause
end

#on_runObject



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

def on_run
end

#on_stopObject



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

def on_stop
end

#pause(wait = true) ⇒ Object



70
71
72
73
74
# File 'lib/dat-tcp.rb', line 70

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

#portObject



97
98
99
# File 'lib/dat-tcp.rb', line 97

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

#run(client_file_descriptors = nil) ⇒ Object

Raises:



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

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)


113
114
115
# File 'lib/dat-tcp.rb', line 113

def running?
  !!@work_loop_thread
end

#serve(socket) ⇒ Object



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

def serve(socket)
  self.serve!(socket)
ensure
  socket.close rescue false
end

#serve!(socket) ⇒ Object

This method should be overwritten to handle new connections



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

def serve!(socket)
end

#stop(wait = true) ⇒ Object



76
77
78
79
80
# File 'lib/dat-tcp.rb', line 76

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

#stop_listeningObject



88
89
90
91
# File 'lib/dat-tcp.rb', line 88

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