nats 0.3.12 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +1 -1
- data/ChangeLog +11 -0
- data/README.md +53 -30
- data/Rakefile +2 -2
- data/bin/nats-queue +21 -0
- data/lib/nats/client.rb +244 -158
- data/lib/nats/ext/em.rb +7 -0
- data/lib/nats/server.rb +9 -291
- data/lib/nats/server/const.rb +32 -22
- data/lib/nats/server/options.rb +63 -31
- data/lib/nats/server/server.rb +307 -0
- data/lib/nats/server/sublist.rb +14 -14
- data/lib/nats/server/util.rb +34 -0
- data/nats.gemspec +12 -8
- metadata +13 -28
data/lib/nats/ext/em.rb
CHANGED
@@ -4,3 +4,10 @@ rescue LoadError
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'eventmachine'
|
6
6
|
end
|
7
|
+
|
8
|
+
# Check for get_outbound_data_size support, fake it out if it doesn't exist, e.g. jruby
|
9
|
+
if !EM::Connection.method_defined? :get_outbound_data_size
|
10
|
+
class EM::Connection
|
11
|
+
def get_outbound_data_size; return 0; end
|
12
|
+
end
|
13
|
+
end
|
data/lib/nats/server.rb
CHANGED
@@ -1,306 +1,25 @@
|
|
1
1
|
|
2
|
-
require File.dirname(__FILE__) + '/ext/em'
|
3
|
-
require File.dirname(__FILE__) + '/ext/bytesize'
|
4
|
-
require File.dirname(__FILE__) + '/ext/json'
|
5
|
-
require File.dirname(__FILE__) + '/server/sublist'
|
6
|
-
require File.dirname(__FILE__) + '/server/options'
|
7
|
-
require File.dirname(__FILE__) + '/server/const'
|
8
|
-
|
9
2
|
require 'socket'
|
10
3
|
require 'fileutils'
|
11
4
|
require 'pp'
|
12
5
|
|
6
|
+
ep = File.expand_path(File.dirname(__FILE__))
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
attr_reader :id, :info, :log_time, :auth_required, :debug_flag, :trace_flag
|
23
|
-
|
24
|
-
alias auth_required? :auth_required
|
25
|
-
alias debug_flag? :debug_flag
|
26
|
-
alias trace_flag? :trace_flag
|
27
|
-
|
28
|
-
def version; "nats server version #{NATSD::VERSION}" end
|
29
|
-
|
30
|
-
def host; @options[:addr] end
|
31
|
-
def port; @options[:port] end
|
32
|
-
def pid_file; @options[:pid_file] end
|
33
|
-
|
34
|
-
def setup(argv)
|
35
|
-
@options = {}
|
36
|
-
|
37
|
-
parser.parse!(argv)
|
38
|
-
read_config_file
|
39
|
-
finalize_options
|
40
|
-
|
41
|
-
@id, @cid = fast_uuid, 1
|
42
|
-
@sublist = Sublist.new
|
43
|
-
@info = {
|
44
|
-
:nats_server_id => Server.id,
|
45
|
-
:version => VERSION,
|
46
|
-
:auth_required => auth_required?,
|
47
|
-
:max_payload => MAX_PAYLOAD_SIZE
|
48
|
-
}
|
49
|
-
|
50
|
-
# Check for daemon flag
|
51
|
-
if @options[:daemonize]
|
52
|
-
require 'rubygems'
|
53
|
-
require 'daemons'
|
54
|
-
# These log messages visible to controlling TTY
|
55
|
-
log "Starting #{NATSD::APP_NAME} version #{NATSD::VERSION} on port #{NATSD::Server.port}"
|
56
|
-
log "Switching to daemon mode"
|
57
|
-
Daemons.daemonize(:app_name => APP_NAME, :mode => :exec)
|
58
|
-
end
|
59
|
-
|
60
|
-
setup_logs
|
61
|
-
|
62
|
-
# Setup optimized select versions
|
63
|
-
EM.epoll unless @options[:noepoll]
|
64
|
-
EM.kqueue unless @options[:nokqueue]
|
65
|
-
|
66
|
-
# Write pid file if need be.
|
67
|
-
File.open(@options[:pid_file], 'w') { |f| f.puts "#{Process.pid}" } if @options[:pid_file]
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def subscribe(subscriber)
|
72
|
-
@sublist.insert(subscriber.subject, subscriber)
|
73
|
-
end
|
74
|
-
|
75
|
-
def unsubscribe(subscriber)
|
76
|
-
@sublist.remove(subscriber.subject, subscriber)
|
77
|
-
end
|
78
|
-
|
79
|
-
def route_to_subscribers(subject, reply, msg)
|
80
|
-
@sublist.match(subject).each do |subscriber|
|
81
|
-
# Skip anyone in the closing state
|
82
|
-
next if subscriber.conn.closing
|
83
|
-
|
84
|
-
trace "Matched subscriber", subscriber[:subject], subscriber[:sid], subscriber.conn.client_info
|
85
|
-
subscriber.conn.send_data("MSG #{subject} #{subscriber.sid} #{reply} #{msg.bytesize}#{CR_LF}")
|
86
|
-
subscriber.conn.send_data(msg)
|
87
|
-
subscriber.conn.send_data(CR_LF)
|
88
|
-
|
89
|
-
# Check the outbound queue here and react if need be..
|
90
|
-
if subscriber.conn.get_outbound_data_size > MAX_OUTBOUND_SIZE
|
91
|
-
subscriber.conn.error_close SLOW_CONSUMER
|
92
|
-
log "Slow consumer dropped", subscriber.conn.client_info
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def auth_ok?(user, pass)
|
98
|
-
user == @options[:user] && pass == @options[:pass]
|
99
|
-
end
|
100
|
-
|
101
|
-
def cid
|
102
|
-
@cid+=1
|
103
|
-
end
|
104
|
-
|
105
|
-
def info_string
|
106
|
-
@info.to_json
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
module Connection #:nodoc:
|
113
|
-
|
114
|
-
attr_reader :cid, :closing
|
115
|
-
|
116
|
-
def client_info
|
117
|
-
@client_info ||= Socket.unpack_sockaddr_in(get_peername)
|
118
|
-
end
|
119
|
-
|
120
|
-
def post_init
|
121
|
-
@cid = Server.cid
|
122
|
-
@subscriptions = {}
|
123
|
-
@verbose = @pedantic = true # suppressed by most clients, but allows friendly telnet
|
124
|
-
@receive_data_calls = 0
|
125
|
-
send_info
|
126
|
-
@auth_pending = EM.add_timer(AUTH_TIMEOUT) { connect_auth_timeout } if Server.auth_required?
|
127
|
-
debug "Client connection created", client_info, cid
|
128
|
-
end
|
129
|
-
|
130
|
-
def connect_auth_timeout
|
131
|
-
error_close AUTH_REQUIRED
|
132
|
-
debug "Connection timeout due to lack of auth credentials", cid
|
133
|
-
end
|
134
|
-
|
135
|
-
def receive_data(data)
|
136
|
-
@receive_data_calls += 1
|
137
|
-
(@buf ||= '') << data
|
138
|
-
close_connection and return if @buf =~ /(\006|\004)/ # ctrl+c or ctrl+d for telnet friendly
|
139
|
-
while (@buf && !@buf.empty? && !@closing)
|
140
|
-
# Waiting on msg payload
|
141
|
-
if @msg_size
|
142
|
-
if (@buf.bytesize >= (@msg_size + CR_LF_SIZE))
|
143
|
-
msg = @buf.slice(0, @msg_size)
|
144
|
-
process_msg(msg)
|
145
|
-
@buf = @buf.slice((msg.bytesize + CR_LF_SIZE), @buf.bytesize)
|
146
|
-
else # Waiting for additional msg data
|
147
|
-
return
|
148
|
-
end
|
149
|
-
# Waiting on control line
|
150
|
-
elsif @buf =~ /^(.*)\r\n/
|
151
|
-
@buf = $'
|
152
|
-
process_op($1)
|
153
|
-
else # Waiting for additional data for control line
|
154
|
-
# This is not normal. Close immediately
|
155
|
-
if @buf.bytesize > MAX_CONTROL_LINE_SIZE
|
156
|
-
debug "MAX_CONTROL_LINE exceeded, closing connection.."
|
157
|
-
@closing = true
|
158
|
-
close_connection
|
159
|
-
end
|
160
|
-
return
|
161
|
-
end
|
162
|
-
end
|
163
|
-
# Nothing should be here.
|
164
|
-
end
|
165
|
-
|
166
|
-
def process_op(op)
|
167
|
-
case op
|
168
|
-
when PUB_OP
|
169
|
-
ctrace 'PUB OP', op
|
170
|
-
return if @auth_pending
|
171
|
-
@pub_sub, @reply, @msg_size, = $1, $3, $4.to_i
|
172
|
-
send_data PAYLOAD_TOO_BIG and return if (@msg_size > MAX_PAYLOAD_SIZE)
|
173
|
-
send_data INVALID_SUBJECT and return if @pedantic && !(@pub_sub =~ SUB_NO_WC)
|
174
|
-
when SUB_OP
|
175
|
-
ctrace 'SUB OP', op
|
176
|
-
return if @auth_pending
|
177
|
-
sub, sid = $1, $2
|
178
|
-
send_data INVALID_SUBJECT and return if !($1 =~ SUB)
|
179
|
-
send_data INVALID_SID_TAKEN and return if @subscriptions[sid]
|
180
|
-
subscriber = Subscriber.new(self, sub, sid)
|
181
|
-
@subscriptions[sid] = subscriber
|
182
|
-
Server.subscribe(subscriber)
|
183
|
-
send_data OK if @verbose
|
184
|
-
when UNSUB_OP
|
185
|
-
ctrace 'UNSUB OP', op
|
186
|
-
return if @xsauth_pending
|
187
|
-
sid, subscriber = $1, @subscriptions[$1]
|
188
|
-
send_data INVALID_SID_NOEXIST and return unless subscriber
|
189
|
-
Server.unsubscribe(subscriber)
|
190
|
-
@subscriptions.delete(sid)
|
191
|
-
send_data OK if @verbose
|
192
|
-
when PING
|
193
|
-
ctrace 'PING OP', op
|
194
|
-
send_data PONG_RESPONSE
|
195
|
-
when CONNECT
|
196
|
-
ctrace 'CONNECT OP', op
|
197
|
-
begin
|
198
|
-
config = JSON.parse($1, :symbolize_keys => true)
|
199
|
-
process_connect_config(config)
|
200
|
-
rescue => e
|
201
|
-
send_data INVALID_CONFIG
|
202
|
-
log_error
|
203
|
-
end
|
204
|
-
when INFO
|
205
|
-
ctrace 'INFO OP', op
|
206
|
-
send_info
|
207
|
-
else
|
208
|
-
ctrace 'Unknown Op', op
|
209
|
-
send_data UNKNOWN_OP
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def send_info
|
214
|
-
send_data "INFO #{Server.info_string}#{CR_LF}"
|
215
|
-
end
|
216
|
-
|
217
|
-
def process_msg(body)
|
218
|
-
ctrace 'Processing msg', @pub_sub, @reply, body
|
219
|
-
send_data OK if @verbose
|
220
|
-
Server.route_to_subscribers(@pub_sub, @reply, body)
|
221
|
-
@pub_sub = @msg_size = @reply = nil
|
222
|
-
true
|
223
|
-
end
|
224
|
-
|
225
|
-
def process_connect_config(config)
|
226
|
-
@verbose = config[:verbose] if config[:verbose] != nil
|
227
|
-
@pedantic = config[:pedantic] if config[:pedantic] != nil
|
228
|
-
|
229
|
-
send_data OK and return unless Server.auth_required?
|
230
|
-
|
231
|
-
EM.cancel_timer(@auth_pending)
|
232
|
-
if Server.auth_ok?(config[:user], config[:pass])
|
233
|
-
send_data OK
|
234
|
-
@auth_pending = nil
|
235
|
-
else
|
236
|
-
error_close AUTH_FAILED
|
237
|
-
debug "Authorization failed for connection", cid
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def error_close(msg)
|
242
|
-
send_data msg
|
243
|
-
close_connection_after_writing
|
244
|
-
@closing = true
|
245
|
-
end
|
246
|
-
|
247
|
-
def unbind
|
248
|
-
debug "Client connection closed", client_info, cid
|
249
|
-
ctrace "Receive_Data called #{@receive_data_calls} times." if @receive_data_calls > 0
|
250
|
-
@subscriptions.each_value { |subscriber| Server.unsubscribe(subscriber) }
|
251
|
-
EM.cancel_timer(@auth_pending) if @auth_pending
|
252
|
-
@auth_pending = nil
|
253
|
-
end
|
254
|
-
|
255
|
-
def ctrace(*args)
|
256
|
-
trace(args, "c: #{cid}")
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
end
|
261
|
-
|
262
|
-
def fast_uuid #:nodoc:
|
263
|
-
v = [rand(0x0010000),rand(0x0010000),rand(0x0010000),
|
264
|
-
rand(0x0010000),rand(0x0010000),rand(0x1000000)]
|
265
|
-
"%04x%04x%04x%04x%04x%06x" % v
|
266
|
-
end
|
267
|
-
|
268
|
-
def log(*args) #:nodoc:
|
269
|
-
args.unshift(Time.now) if NATSD::Server.log_time
|
270
|
-
pp args.compact
|
271
|
-
end
|
272
|
-
|
273
|
-
def debug(*args) #:nodoc:
|
274
|
-
log *args if NATSD::Server.debug_flag?
|
275
|
-
end
|
276
|
-
|
277
|
-
def trace(*args) #:nodoc:
|
278
|
-
log *args if NATSD::Server.trace_flag?
|
279
|
-
end
|
280
|
-
|
281
|
-
def log_error(e=$!) #:nodoc:
|
282
|
-
debug e, e.backtrace
|
283
|
-
end
|
284
|
-
|
285
|
-
def shutdown #:nodoc:
|
286
|
-
puts
|
287
|
-
log 'Server exiting..'
|
288
|
-
EM.stop
|
289
|
-
FileUtils.rm(NATSD::Server.pid_file) if NATSD::Server.pid_file
|
290
|
-
exit
|
291
|
-
end
|
292
|
-
|
293
|
-
['TERM','INT'].each { |s| trap(s) { shutdown } }
|
8
|
+
require "#{ep}/ext/em"
|
9
|
+
require "#{ep}/ext/bytesize"
|
10
|
+
require "#{ep}/ext/json"
|
11
|
+
require "#{ep}/server/server"
|
12
|
+
require "#{ep}/server/sublist"
|
13
|
+
require "#{ep}/server/options"
|
14
|
+
require "#{ep}/server/const"
|
15
|
+
require "#{ep}/server/util"
|
294
16
|
|
295
17
|
# Do setup
|
296
18
|
NATSD::Server.setup(ARGV.dup)
|
297
19
|
|
298
20
|
# Event Loop
|
299
|
-
|
300
21
|
EM.run {
|
301
|
-
|
302
22
|
log "Starting #{NATSD::APP_NAME} version #{NATSD::VERSION} on port #{NATSD::Server.port}"
|
303
|
-
|
304
23
|
begin
|
305
24
|
EM.set_descriptor_table_size(32768) # Requires Root privileges
|
306
25
|
EventMachine::start_server(NATSD::Server.host, NATSD::Server.port, NATSD::Connection)
|
@@ -309,5 +28,4 @@ EM.run {
|
|
309
28
|
log_error
|
310
29
|
exit
|
311
30
|
end
|
312
|
-
|
313
31
|
}
|
data/lib/nats/server/const.rb
CHANGED
@@ -1,51 +1,61 @@
|
|
1
|
+
|
1
2
|
module NATSD #:nodoc:
|
2
3
|
|
3
|
-
VERSION = '0.
|
4
|
+
VERSION = '0.4.2'
|
4
5
|
APP_NAME = 'nats-server'
|
5
6
|
|
6
7
|
DEFAULT_PORT = 4222
|
8
|
+
DEFAULT_HOST = '0.0.0.0'
|
7
9
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
SUB_OP = /^SUB\s+(\S+)\s+(\S+)$/i
|
12
|
-
UNSUB_OP = /^UNSUB\s+(\S+)$/i
|
13
|
-
PING = /^PING$/i
|
14
|
-
CONNECT = /^CONNECT\s+(.+)$/i
|
15
|
-
|
16
|
-
# 1k should be plenty since payloads sans connect are payload
|
17
|
-
MAX_CONTROL_LINE_SIZE = 1024
|
18
|
-
|
19
|
-
# Should be using something different if > 1MB payload
|
20
|
-
MAX_PAYLOAD_SIZE = (1024*1024)
|
10
|
+
# Parser
|
11
|
+
AWAITING_CONTROL_LINE = 1
|
12
|
+
AWAITING_MSG_PAYLOAD = 2
|
21
13
|
|
22
|
-
#
|
23
|
-
|
14
|
+
# Ops - See protocol.txt for more info
|
15
|
+
INFO = /\AINFO\r\n/i
|
16
|
+
PUB_OP = /\APUB\s+([^\s\r\n]+)\s+(([^\s\r\n]+)[^\S\r\n]+)?(\d+)\r\n/i
|
17
|
+
SUB_OP = /\ASUB\s+([^\s\r\n]+)\s+(([^\s\r\n]+)[^\S\r\n]+)?([^\s\r\n]+)\r\n/i
|
18
|
+
UNSUB_OP = /\AUNSUB\s+([^\s\r\n]+)\s*(\s+(\d+))?\r\n/i
|
19
|
+
PING = /\APING\r\n/i
|
20
|
+
CONNECT = /\ACONNECT\s+([^\r\n]+)\r\n/i
|
21
|
+
UNKNOWN = /\A(.*)\r\n/
|
24
22
|
|
25
23
|
# RESPONSES
|
26
24
|
CR_LF = "\r\n".freeze
|
27
25
|
CR_LF_SIZE = CR_LF.bytesize
|
28
|
-
|
26
|
+
EMPTY = ''.freeze
|
27
|
+
OK = "+OK#{CR_LF}".freeze
|
29
28
|
PONG_RESPONSE = "PONG#{CR_LF}".freeze
|
30
|
-
|
31
29
|
INFO_RESPONSE = "#{CR_LF}".freeze
|
32
30
|
|
33
31
|
# ERR responses
|
34
|
-
PAYLOAD_TOO_BIG = "-ERR 'Payload size exceeded
|
32
|
+
PAYLOAD_TOO_BIG = "-ERR 'Payload size exceeded'#{CR_LF}".freeze
|
33
|
+
PROTOCOL_OP_TOO_BIG = "-ERR 'Protocol Operation size exceeded'#{CR_LF}".freeze
|
35
34
|
INVALID_SUBJECT = "-ERR 'Invalid Subject'#{CR_LF}".freeze
|
36
35
|
INVALID_SID_TAKEN = "-ERR 'Invalid Subject Identifier (sid), already taken'#{CR_LF}".freeze
|
37
36
|
INVALID_SID_NOEXIST = "-ERR 'Invalid Subject-Identifier (sid), no subscriber registered'#{CR_LF}".freeze
|
38
37
|
INVALID_CONFIG = "-ERR 'Invalid config, valid JSON required for connection configuration'#{CR_LF}".freeze
|
39
38
|
AUTH_REQUIRED = "-ERR 'Authorization is required'#{CR_LF}".freeze
|
40
39
|
AUTH_FAILED = "-ERR 'Authorization failed'#{CR_LF}".freeze
|
41
|
-
UNKNOWN_OP = "-ERR '
|
40
|
+
UNKNOWN_OP = "-ERR 'Unknown Protocol Operation'#{CR_LF}".freeze
|
42
41
|
SLOW_CONSUMER = "-ERR 'Slow consumer detected, connection dropped'#{CR_LF}".freeze
|
43
42
|
|
44
43
|
# Pedantic Mode
|
45
44
|
SUB = /^([^\.\*>\s]+|>$|\*)(\.([^\.\*>\s]+|>$|\*))*$/
|
46
45
|
SUB_NO_WC = /^([^\.\*>\s]+)(\.([^\.\*>\s]+))*$/
|
47
46
|
|
48
|
-
#
|
49
|
-
|
47
|
+
# Some sane default thresholds
|
48
|
+
|
49
|
+
# 1k should be plenty since payloads sans connect string are separate
|
50
|
+
MAX_CONTROL_LINE_SIZE = 1024
|
51
|
+
|
52
|
+
# Should be using something different if > 1MB payload
|
53
|
+
MAX_PAYLOAD_SIZE = (1024*1024)
|
54
|
+
|
55
|
+
# Maximum outbound size per client
|
56
|
+
MAX_PENDING_SIZE = (10*1024*1024)
|
57
|
+
|
58
|
+
# Authorization wait time
|
59
|
+
AUTH_TIMEOUT = 1
|
50
60
|
|
51
61
|
end
|
data/lib/nats/server/options.rb
CHANGED
@@ -8,44 +8,45 @@ module NATSD
|
|
8
8
|
class << self
|
9
9
|
def parser
|
10
10
|
@parser ||= OptionParser.new do |opts|
|
11
|
-
opts.banner = "Usage: nats [options]"
|
11
|
+
opts.banner = "Usage: nats-server [options]"
|
12
12
|
|
13
13
|
opts.separator ""
|
14
14
|
opts.separator "Server options:"
|
15
15
|
|
16
16
|
opts.on("-a", "--addr HOST", "Bind to HOST address " +
|
17
|
-
"(default: #{
|
18
|
-
opts.on("-p", "--port PORT", "Use PORT (default: #{
|
17
|
+
"(default: #{DEFAULT_HOST})") { |host| @options[:addr] = host }
|
18
|
+
opts.on("-p", "--port PORT", "Use PORT (default: #{DEFAULT_PORT})") { |port| @options[:port] = port.to_i }
|
19
|
+
opts.on("-d", "--daemonize", "Run daemonized in the background") { @options[:daemonize] = true }
|
20
|
+
opts.on("-P", "--pid FILE", "File to store PID") { |file| @options[:pid_file] = file }
|
19
21
|
|
20
|
-
opts.on("-
|
21
|
-
|
22
|
-
"(default: #{@options[:log_file]})") { |file| @options[:log_file] = file }
|
23
|
-
opts.on("-T", "--logtime", "Timestamp log entries") { @options[:log_time] = true }
|
22
|
+
opts.on("-C", "--config FILE", "Configuration File " +
|
23
|
+
"(default: #{@options[:config_file]})") { |file| @options[:config_file] = file }
|
24
24
|
|
25
|
-
opts.
|
26
|
-
|
25
|
+
opts.separator ""
|
26
|
+
opts.separator "Logging options:"
|
27
27
|
|
28
|
-
opts.on("-
|
29
|
-
|
28
|
+
opts.on("-l", "--log FILE", "File to redirect log output") { |file| @options[:log_file] = file }
|
29
|
+
opts.on("-T", "--logtime", "Timestamp log entries (default: false)") { @options[:log_time] = true }
|
30
|
+
opts.on("-D", "--debug", "Enable debugging output") { @options[:debug] = true }
|
31
|
+
opts.on("-V", "--trace", "Trace the raw protocol") { @options[:trace] = true }
|
30
32
|
|
31
33
|
opts.separator ""
|
32
|
-
opts.separator "Authorization options:
|
34
|
+
opts.separator "Authorization options:"
|
33
35
|
|
34
|
-
opts.on("--user user", "User required for connections")
|
36
|
+
opts.on("--user user", "User required for connections") { |user| @options[:user] = user }
|
37
|
+
opts.on("--pass password", "Password required for connections") { |pass| @options[:pass] = pass }
|
35
38
|
|
36
|
-
opts.
|
37
|
-
opts.
|
39
|
+
opts.separator ""
|
40
|
+
opts.separator "Advanced IO options:"
|
38
41
|
|
39
|
-
opts.on("--no_epoll", "
|
40
|
-
opts.on("--
|
42
|
+
opts.on("--no_epoll", "Disable epoll (Linux)") { @options[:noepoll] = true }
|
43
|
+
opts.on("--no_kqueue", "Disable kqueue (MacOSX and BSD)") { @options[:nokqueue] = true }
|
41
44
|
|
42
45
|
opts.separator ""
|
43
46
|
opts.separator "Common options:"
|
44
47
|
|
45
|
-
opts.on_tail("-h", "--help", "Show this message")
|
46
|
-
opts.on_tail('-v', '--version', "Show version")
|
47
|
-
opts.on_tail("-D", "--debug", "Set debugging on") { @options[:debug] = true }
|
48
|
-
opts.on_tail("-V", "--trace", "Set tracing on of raw protocol") { @options[:trace] = true }
|
48
|
+
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
49
|
+
opts.on_tail('-v', '--version', "Show version") { puts NATSD::Server.version; exit }
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -53,13 +54,32 @@ module NATSD
|
|
53
54
|
return unless config_file = @options[:config_file]
|
54
55
|
config = File.open(config_file) { |f| YAML.load(f) }
|
55
56
|
# Command lines args, parsed first, will override these.
|
56
|
-
[:
|
57
|
-
|
58
|
-
|
57
|
+
@options[:port] = config['port'] if @options[:port].nil?
|
58
|
+
@options[:addr] = config['net'] if @options[:addr].nil?
|
59
|
+
if auth = config['authorization']
|
60
|
+
@options[:user] = auth['user'] if @options[:user].nil?
|
61
|
+
@options[:pass] = auth['password'] if @options[:pass].nil?
|
62
|
+
@options[:token] = auth['token'] if @options[:token].nil?
|
63
|
+
@options[:auth_timeout] = auth['timeout'] if @options[:auth_timeout].nil?
|
59
64
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
65
|
+
@options[:pid_file] = config['pid_file'] if @options[:pid_file].nil?
|
66
|
+
@options[:log_file] = config['log_file'] if @options[:log_file].nil?
|
67
|
+
@options[:logtime] = config['logtime'] if @options[:logtime].nil?
|
68
|
+
@options[:debug] = config['debug'] if @options[:debug].nil?
|
69
|
+
@options[:trace] = config['trace'] if @options[:trace].nil?
|
70
|
+
|
71
|
+
# these just override if present
|
72
|
+
@options[:max_control_line] = config['max_control_line'] if config['max_control_line']
|
73
|
+
@options[:max_payload] = config['max_payload'] if config['max_payload']
|
74
|
+
@options[:max_pending] = config['max_pending'] if config['max_pending']
|
75
|
+
|
76
|
+
# just set
|
77
|
+
@options[:noepoll] = config['no_epoll'] if config['no_epoll']
|
78
|
+
@options[:nokqueue] = config['no_kqueue'] if config['no_kqueue']
|
79
|
+
|
80
|
+
rescue => e
|
81
|
+
log "Could not read configuration file: #{e}"
|
82
|
+
exit
|
63
83
|
end
|
64
84
|
|
65
85
|
def setup_logs
|
@@ -72,7 +92,7 @@ module NATSD
|
|
72
92
|
def finalize_options
|
73
93
|
# Addr/Port
|
74
94
|
@options[:port] ||= DEFAULT_PORT
|
75
|
-
@options[:addr] ||=
|
95
|
+
@options[:addr] ||= DEFAULT_HOST
|
76
96
|
|
77
97
|
# Debug and Tracing
|
78
98
|
@debug_flag = @options[:debug]
|
@@ -80,14 +100,26 @@ module NATSD
|
|
80
100
|
|
81
101
|
# Log timestamps
|
82
102
|
@log_time = @options[:log_time]
|
83
|
-
# setup_logs
|
84
103
|
|
85
104
|
debug @options # Block pass?
|
86
105
|
debug "DEBUG is on"
|
87
106
|
trace "TRACE is on"
|
88
107
|
|
89
|
-
#
|
90
|
-
@auth_required = (@options[:user]
|
108
|
+
# Authorization
|
109
|
+
@auth_required = (not @options[:user].nil?)
|
110
|
+
|
111
|
+
# Thresholds
|
112
|
+
@options[:max_control_line] ||= MAX_CONTROL_LINE_SIZE
|
113
|
+
@max_control_line = @options[:max_control_line]
|
114
|
+
|
115
|
+
@options[:max_payload] ||= MAX_PAYLOAD_SIZE
|
116
|
+
@max_payload = @options[:max_payload]
|
117
|
+
|
118
|
+
@options[:max_pending] ||= MAX_PENDING_SIZE
|
119
|
+
@max_pending = @options[:max_pending]
|
120
|
+
|
121
|
+
@options[:auth_timeout] ||= AUTH_TIMEOUT
|
122
|
+
@auth_timeout = @options[:auth_timeout]
|
91
123
|
end
|
92
124
|
|
93
125
|
end
|