kinetic-ruby 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b867b06ff9ff5869339c23c1e75c77e592a4927
4
- data.tar.gz: 463579647bc42a1cb002bd24412696572c683e85
3
+ metadata.gz: 7f7c34a6be5838b4d0dfb7fdee59c5e4ce5678da
4
+ data.tar.gz: be5746db50b0fea02b0f89c91279b7dc74ea0771
5
5
  SHA512:
6
- metadata.gz: 8e3e14bb6f463040bee482b4eb15eb9c64757d7a536add1e7a542b0476a02715349eb5d66b382aa92c860ca1ba77a172f7ad5ec26aa2de48da1b1a007e54bf14
7
- data.tar.gz: b87f4e1e204d5b2781d910232b5854041a7ee000873b6150a5cf9da4109e75c3eaebdf8aa7f61c13ba93f8569ed9954a66ba0368b4dd061bdb4e247ebccd5e35
6
+ metadata.gz: 87433d1fa160efdac86af6f9e2eb22e43fbcad3f2def7fc3f309559b319e8a0acbdc6b9d10db007d102fc5e961a3ad92b81f6d049d05da33f7d9d3fc540a2bcc
7
+ data.tar.gz: 41389bc4b0bbc3cef02b0793e930767796669a09865dee1295c2d3b585fd12317a333035bd5df297c5ab8cd09428bd713fed174643e240e61cdadcd2ad7d9402
data/Rakefile CHANGED
@@ -11,18 +11,17 @@ namespace :test do
11
11
  desc "Test Kinetic Ruby server"
12
12
  task :server => 'kinetic:server:start' do
13
13
  report "Started Kinetic Ruby server!"
14
- sleep 2.0
15
14
  client = Thread.new do
16
- report "Connecting test client to #{$kinetic_server.host}:#{$kinetic_server.port}..."
17
- sh "telnet #{$kinetic_server.host} #{$kinetic_server.port}"
15
+ addr = $kinetic_server.host + ':' + $kinetic_server.port.to_s
16
+ report "Connecting test client to #{addr}\n"
17
+ client = TCPSocket.new('localhost', KineticRuby::DEFAULT_KINETIC_PORT)
18
+ raise "Failed connecting to server!" unless client
19
+ report "Connected to server!"
20
+ client.close
18
21
  end
19
- sleep 1.0
20
- raise "Failed connecting a client to Kinetic Ruby server!" unless $kinetic_server.connected
21
- client.exit
22
- client.join(2.0)
22
+ client.join 5.0
23
23
  $kinetic_server.shutdown unless $kinetic_server.nil?
24
24
  $kinetic_server = nil
25
- sleep 2.0
26
25
  report "Kinetic Ruby server test successful!"
27
26
  end
28
27
  end
@@ -105,6 +104,7 @@ end
105
104
 
106
105
  def report(msg='', banner=false)
107
106
  $stderr.flush
107
+ $stdout.flush
108
108
  if banner
109
109
  len = msg.length
110
110
  msg = "\n#{msg}\n#{'-'*len}"
@@ -1,6 +1,6 @@
1
- # Preload all library files
1
+ # Preload library files
2
2
  require 'fileutils'
3
-
3
+ require 'socket'
4
4
  FileUtils.cd(File.dirname(__FILE__)) do
5
5
  Dir['./**/*.rb'].each do |f|
6
6
  mod = f.sub(/.rb/, '')
@@ -9,11 +9,17 @@ FileUtils.cd(File.dirname(__FILE__)) do
9
9
  end
10
10
 
11
11
  module KineticRuby
12
+
13
+ # Rake extensions for kinetic-ruby
12
14
  module Rake
15
+ # Call from Rakefile to load kinetic-ruby Rake tasks (after requiring this file)
13
16
  def self.load_tasks
14
17
  Dir["#{File.dirname(__FILE__)}/../tasks/**/*.rake"].each do |tasks|
15
18
  load tasks
16
19
  end
17
20
  end
21
+
22
+ # Autoload rake tasks if Rake already loaded
23
+ load_tasks if defined?(Rake)
18
24
  end
19
25
  end
@@ -0,0 +1,2 @@
1
+ module KineticRuby
2
+ end
@@ -0,0 +1,4 @@
1
+ module KineticRuby
2
+ DEFAULT_KINETIC_PORT = 8123
3
+ TEST_KINETIC_PORT = 8999
4
+ end
@@ -12,6 +12,7 @@ module KineticRuby
12
12
  def initialize(log_level=LOG_LEVEL_INFO, stream=$stdout)
13
13
  set_level log_level
14
14
  @stream = stream
15
+ @prefix = ''
15
16
  end
16
17
 
17
18
  def level=(log_level)
@@ -22,6 +23,14 @@ module KineticRuby
22
23
  @level.dup
23
24
  end
24
25
 
26
+ def prefix=(msg)
27
+ @prefix = msg if msg
28
+ end
29
+
30
+ def prefix
31
+ @prefix.dup if @prefix
32
+ end
33
+
25
34
  def log_info(msg='', banner=nil)
26
35
  log_message(msg, banner) if @level >= LOG_LEVEL_INFO
27
36
  end
@@ -38,6 +47,14 @@ module KineticRuby
38
47
  end
39
48
  alias logv log_verbose
40
49
 
50
+ def log_exception(exception, desc=nil, level=LOG_LEVEL_ERROR)
51
+ log_err(desc) if (desc && !desc.empty?)
52
+ log_err "Exception #{exception.class} '#{exception.message}' occured at:"
53
+ exception.backtrace.each do |l|
54
+ log_err " #{l}"
55
+ end
56
+ end
57
+
41
58
  private
42
59
 
43
60
  def set_level(log_level)
@@ -48,10 +65,9 @@ module KineticRuby
48
65
  @level = log_level
49
66
  end
50
67
 
51
- LOG_BANNER = "\n----------------------------------------"
52
-
53
68
  def log_message(msg, banner)
54
- msg += LOG_BANNER if (banner && msg && !msg.empty?)
69
+ msg = @prefix + msg if (@prefix && !@prefix.empty?)
70
+ msg += "\n" + @prefix + ('-'*40) if (banner && msg && !msg.empty?)
55
71
  @stream.puts msg
56
72
  @stream.flush
57
73
  end
@@ -4,56 +4,122 @@ module KineticRuby
4
4
 
5
5
  class PDU
6
6
 
7
+ HEADER_LENGTH = 1 + 4 + 4 # version_prefix + protobuf_length + value_length
8
+
7
9
  def initialize(logger, raw=nil)
8
10
  raise "Invalid logger specified!" unless logger
9
11
  @logger = logger
10
- parse(raw)
12
+ @header = nil
13
+ @protobuf = nil
14
+ @value = nil
15
+ parse(raw) unless raw.nil?
16
+ end
17
+
18
+ def complete?
19
+ complete = false
20
+ if @header && @protobuf
21
+ if @header['valueLength'] == 0
22
+ complete = true
23
+ elsif @value && (@value.length >= @header['valueLength'])
24
+ complete = true
25
+ end
26
+ end
27
+ return complete
11
28
  end
12
29
 
13
30
  def parse(raw)
14
- @header = parse_header(raw)
15
- @protobuf = parse_protobuf(raw) if @header
16
- @value = parse_value(raw) if (@header && @protobuf)
17
- return (@header && @protobuf && @value)
31
+ if parse_header(raw)
32
+ @logger.log 'PDU Header:'
33
+ @header.each_pair{|k,v| @logger.log " #{k}: #{v}"}
34
+
35
+ if parse_protobuf(raw)
36
+ @logger.log 'PDU Protobuf:'
37
+ @protobuf.to_yaml.each_line{|l| @logger.log(' ' + l)}
38
+
39
+ if @header['valueLength'] > 0 && parse_value(raw)
40
+ @logger.log 'PDU Value:'
41
+ @logger.log " #{@value.to_s}"
42
+ end
43
+ end
44
+ end
45
+
46
+ return complete?
47
+ end
48
+
49
+ def self.valid_header?(raw)
50
+ (
51
+ !raw.nil? &&
52
+ raw.length >= HEADER_LENGTH &&
53
+ raw[0] == KineticRuby::Proto::VERSION_PREFIX
54
+ )
18
55
  end
19
56
 
20
57
  def length
21
58
  len = 0
22
59
  len += HEADER_LENGTH if @header
23
- len += @header[:protobuf_length] if @protobuf
24
- len += @header[:value_length] if @value
60
+ len += @header['protobufLength'] if @protobuf
61
+ len += @header['valueLength'] if @value
25
62
  return len
26
63
  end
27
64
  alias size length
28
65
 
29
- private
66
+ def dump
67
+ return unless complete?
68
+
69
+ @logger.log('PDU Content', true)
30
70
 
31
- HEADER_LENGTH = 1 + 4 + 4 # version_prefix + protobuf_length + value_length
71
+ # Log the header
72
+ @logger.log " header:\n" +
73
+ " version_prefix: #{@header['versionPrefix']}\n" +
74
+ " protobuf_length: #{@header['protobufLength']}\n" +
75
+ " value_length: #{@header['valueLength']}\n"
76
+
77
+ # Log the protobuf
78
+ @logger.log " protobuf:\n" + Proto.to_yaml(@protobuf, ' ')
79
+
80
+ # Log the value payload
81
+ @logger.log " value: (#{value.length} bytes)\n"
82
+ if @logger.level >= Logger::LOG_LEVEL_VERBOSE
83
+ val = @value.dup
84
+ val_string = ''
85
+ while !val.empty?
86
+ val_string += " #{val.slice!(i,8)}\n"
87
+ end
88
+ @logger.logv val_string
89
+ end
90
+ end
91
+
92
+ private
32
93
 
33
94
  def parse_header(raw)
34
- return nil unless (raw && raw.length <= HEADER_LENGTH)
35
- {
36
- version_prefix: raw[0],
37
- protobuf_length: parse_nbo_int32(raw.byteslice(1..4)),
38
- value_length: parse_nbo_int32(raw.byteslice(5..9))
95
+ if (!raw || raw.length <= HEADER_LENGTH)
96
+ @logger.log "Haven't recevived the full PDU header yet..."
97
+ @logger.log " header: raw: #{raw.inspect}" unless (!raw || raw.empty?)
98
+ return nil
99
+ end
100
+ @header = {
101
+ 'versionPrefix' => raw[0],
102
+ 'protobufLength' => parse_nbo_int32(raw.byteslice(1..4)),
103
+ 'valueLength' => parse_nbo_int32(raw.byteslice(5..8)),
39
104
  }
40
105
  end
41
106
 
42
107
  def parse_protobuf(raw)
43
- min_length = (HEADER_LENGTH + @header[:protobuf_length])
108
+ min_length = (HEADER_LENGTH + @header['protobufLength'])
44
109
  return nil unless (@header && raw.length >= min_length)
45
110
  start_idx = HEADER_LENGTH
46
111
  end_idx = HEADER_LENGTH + min_length - 1
47
112
  protobuf = raw.byteslice(start_idx, end_idx)
48
- Seagate::Kinetic::Message.decode(protobuf)
113
+ @protobuf = Seagate::Kinetic::Message.decode(protobuf)
49
114
  end
50
115
 
51
116
  def parse_value(raw)
52
- min_length = (HEADER_LENGTH + @header[:protobuf_length] + @header[:value_length])
117
+ preamble_length = HEADER_LENGTH + @header['protobufLength']
118
+ min_length = preamble_length + 1
119
+ full_length = preamble_length + @header['valueLength']
53
120
  return nil unless (@header && @protobuf && raw.length >= min_length)
54
- start_idx = HEADER_LENGTH + @header[:protobuf_length]
55
- end_idx = start_idx + @header[:protobuf_length] - 1
56
- @value = raw.byteslice(start_idx, end_idx)
121
+ end_idx = preamble_length + @header['protobufLength'] - 1
122
+ @value = raw.byteslice(preamble_length, end_idx)
57
123
  end
58
124
 
59
125
  def parse_nbo_int32(data)
@@ -12,19 +12,43 @@ module KineticRuby
12
12
  @message_in = nil
13
13
  end
14
14
 
15
- def decode(buf)
16
- @message_in = Seagate::Kinetic::Message.decode(buf)
17
- @logger.log
18
- @logger.log("\n#{@message_in.class} - Decoding", true)
19
- @logger.log ' command:'
20
- @message_in.command.to_yaml.each_line{|line| @logger.log ' ' + line}
21
- @logger.log
15
+ def self.decode(buf, indent=0, logger=nil)
16
+ msg = Seagate::Kinetic::Message.decode(buf)
17
+
18
+ # Log the decoded protobuf
19
+ if logger
20
+ orig_prefix = logger.prefix
21
+ add_prefix = (indent.class == Fixnum) ? (' '*indent) : indent
22
+ add_prefix = ' ' * indent
23
+ logger.prefix = logger.prefix + add_prefix
24
+ logger.log 'message:'
25
+ logger.prefix = logger.prefix + ' '
26
+ self.to_yaml(msg).each_line{|line| logger.log(line) }
27
+ logger.prefix = orig_prefix
28
+ logger.log
29
+ end
30
+
31
+ return msg
32
+ end
33
+
34
+ def decode(buf, indent=0)
35
+ @message_in = Proto.decode(buf, indent, @logger)
36
+ end
37
+
38
+ def self.to_yaml(msg)
39
+ yaml = "message:\n"
40
+ msg.to_yaml.each_line{|line| yaml += " #{line}"}
41
+ return yaml
42
+ end
43
+
44
+ def to_yaml(msg)
45
+ self.to_yaml(msg)
22
46
  end
23
47
 
24
48
  def test_encode
25
49
  pb = Seagate::Kinetic::Message.new
26
-
27
- @logger.log("\n#{pb.class} - Encoding", true)
50
+ @logger.log
51
+ @logger.log("#{pb.class} - Encoding", true)
28
52
  pb.hmac = '0123456789ABCDEF0123'
29
53
  pb.command = Seagate::Kinetic::Message::Command.new(
30
54
  header: Seagate::Kinetic::Message::Header.new(
@@ -47,14 +71,16 @@ module KineticRuby
47
71
 
48
72
  @logger.log_verbose ' fields:'
49
73
  pb.fields.sort.each{|f| @logger.log_verbose(" #{f}")}
50
- @logger.log_verbose " hmac:\n #{pb.hmac}"
74
+ @logger.log_verbose " hmac:"
75
+ @logger.log_verbose " #{pb.hmac}"
51
76
 
52
77
  @logger.log ' command:'
53
78
  pb.command.to_yaml.each_line{|l| @logger.log(" #{l}")}
54
79
  @logger.log ' encoded:'
55
80
  @logger.log ' Length: ' + encoded.length.to_s + ' bytes'
56
81
 
57
- @logger.log_verbose " Raw:\n #{encoded.inspect}"
82
+ @logger.log_verbose " Raw:"
83
+ @logger.log_verbose " #{encoded.inspect}"
58
84
  @logger.log_verbose " Content:"
59
85
  encoded.to_yaml.each_line{|line| @logger.log_verbose " #{line}"}
60
86
 
@@ -65,10 +91,14 @@ module KineticRuby
65
91
 
66
92
  def test_kinetic_proto
67
93
  msg = test_encode
68
- decode msg
94
+
95
+ @logger.log
96
+ @logger.log("Decoded Message", true)
97
+ decode(msg, 2)
69
98
 
70
99
  if @message_in != @message_out
71
- @logger.log_err "Inbound/outbound messages do not match!\n\n"
100
+ @logger.log_err "Inbound/outbound messages do not match!"
101
+ @logger.log_err
72
102
  raise "\nKinetic Protocol message roundtrip FAILED!\n\n"
73
103
  end
74
104
 
@@ -1,11 +1,144 @@
1
- require 'socket'
2
-
3
1
  $kinetic_server = nil
2
+ require_relative 'kinetic_constants'
4
3
 
5
4
  module KineticRuby
6
5
 
7
- DEFAULT_KINETIC_PORT = 8123
8
- TEST_KINETIC_PORT = 8999
6
+ class Client
7
+ def initialize(socket, addr_info, logger)
8
+ @socket = socket
9
+ @addr = addr_info
10
+ @logger = logger
11
+ end
12
+
13
+ # Shutdown a client socket
14
+ def close
15
+ return unless @socket
16
+ @logger.log "Client socket #{@socket.inspect} disconnected!"
17
+ @socket.close
18
+ @socket = nil
19
+ @logger.logv "Client #{@socket.inspect} connection shutdown successfully"
20
+ end
21
+
22
+ # Return formatted address '<address>:<port>' for the socket
23
+ def self.address(socket)
24
+ return nil unless socket
25
+ raise "Socket appears to be disconnected!" if !socket.remote_address
26
+ "#{socket.remote_address.ip_address}:#{socket.remote_address.ip_port}"
27
+ end
28
+
29
+ # Return formatted address '<address>:<port>' of the client
30
+ def address
31
+ Client.address(@socket)
32
+ end
33
+
34
+ # Wait to receive data from the client
35
+ # @param max_len Maximum number of bytes to receive
36
+ # @returns Received data (length <= max_len) or nil upon failure
37
+ def receive(max_len=nil)
38
+ max_len ||= 1024
39
+
40
+ begin
41
+ data = @socket.recv(max_len)
42
+ rescue IO::WaitReadable
43
+ @logger.logv 'Retrying receive...'
44
+ IO.select([@socket])
45
+ retry
46
+ rescue Exception => e
47
+ if e.class != 'IOError' && e.message != 'closed stream'
48
+ @logger.log_exception(e, 'EXCEPTION during receive!')
49
+ end
50
+ end
51
+
52
+ if (data.nil? || data.empty?)
53
+ @logger.log "Client #{@socket.inspect} disconnected!"
54
+ data = ''
55
+ else
56
+ @logger.log "Received #{data.length} bytes"
57
+ end
58
+
59
+ return data
60
+ end
61
+ alias recv receive # provide 'standard' socket method as well
62
+
63
+ # Send data to the client
64
+ def send(data)
65
+ @socket.write(data)
66
+ end
67
+ alias write send # provide 'standard' socket method as well
68
+
69
+ end
70
+
71
+ class ClientProvider
72
+ def initialize(host, port, logger)
73
+ @host = host
74
+ @port = port
75
+ @logger = logger
76
+ @server = nil
77
+ end
78
+
79
+ # @brief Listen for connection
80
+ # @return Returns a Client upon connection, nil upon failure
81
+ def accept
82
+ client = nil
83
+ @server ||= TCPServer.new(@host, @port)
84
+
85
+ begin
86
+ client = Client.new(@server.accept)
87
+ rescue Exception => e
88
+ @logger.log_exception(e, 'EXCEPTION during accept!')
89
+ end
90
+
91
+ @logger.log 'Client dropped off!' if client.nil?
92
+
93
+ return client
94
+ end
95
+
96
+ # @brief Shutdown the socket server
97
+ def shutdown
98
+ return if @server.nil?
99
+ @server.close
100
+ @server = nil
101
+ end
102
+
103
+ # @brief Starts a TCP socket server and yields block for each client (sequential)
104
+ # @param host Host name or IPv4/6 address
105
+ # @param port Port to listen on
106
+ # @param logger Logger to output to
107
+ def self.each_client(host, port, logger)
108
+ raise "No block supplied!" unless block_given?
109
+ logger.log "Listening for clients..."
110
+
111
+ # Service clients, one at a time (for now at least)
112
+ begin
113
+ Socket.tcp_server_loop(host, port) do |socket, addr|
114
+
115
+ logger.log "New client connected on socket #{socket.inspect}"
116
+
117
+ client = Client.new(socket, addr, logger)
118
+ raise "Failed to connect to client!" unless client
119
+ logger.log "Connected to #{client.address}"
120
+
121
+ begin
122
+ # Execute the supplied block with the connected client
123
+ yield(client, logger)
124
+ logger.log "Done servicing client #{client.address}"
125
+ ensure
126
+ logger.log "Closing client socket..."
127
+ # Make sure the client gets closed, since tcp_server_loop does NOT!
128
+ client.close
129
+ logger.log "Client socket shutdown!"
130
+ end
131
+ logger.log "Done with client #{client.address}"
132
+ end
133
+
134
+ rescue Exception => e
135
+ logger.log_exception(e, 'EXCEPTION during listen!')
136
+ end
137
+
138
+ logger.log "Done listening for clients!"
139
+ end
140
+
141
+ end
9
142
 
10
143
  class Server
11
144
 
@@ -14,17 +147,11 @@ module KineticRuby
14
147
  def initialize(port = DEFAULT_KINETIC_PORT, log_level=Logger::LOG_LEVEL_INFO)
15
148
  @host = 'localhost'
16
149
  @port ||= DEFAULT_KINETIC_PORT
17
- raise "Invalid Kinetic test server port specified (port: #{port})" if !@port || @port < 0
150
+ raise "Invalid server port specified: #{port}" if !@port || @port < 0
18
151
  @logger = Logger.new(log_level)
19
- @proto = Proto.new(@logger)
20
- @server = nil
152
+ @logger.prefix = 'KineticSim: '
21
153
  @worker = nil
22
- @clients = []
23
- @logger.log "Kinetic Ruby test device server started!"
24
- end
25
-
26
- def connected
27
- !@server.nil?
154
+ @logger.log 'Kinetic device test server started!'
28
155
  end
29
156
 
30
157
  def report_buffer(buf)
@@ -46,103 +173,105 @@ module KineticRuby
46
173
  end
47
174
 
48
175
  def start
49
- return unless @server.nil?
50
-
51
- @server = TCPServer.new(@host, @port)
176
+ return unless @worker.nil?
52
177
 
53
178
  # Setup handler for signaled shutdown (via ctrl+c)
54
179
  trap("INT") do
55
- @logger.log "Kinetic Test Server: INT triggered Kintic Test Server shutdown"
180
+ @logger.log "INT triggered shutdown"
56
181
  shutdown
57
182
  end
58
183
 
59
- # Create worker thread for test server to run in so we can continue
184
+ # Create background thread for processing client requests
60
185
  @worker = Thread.new do
61
- @logger.log "Kinetic Test Server: Listening for Kinetic clients..."
62
- loop do
63
- client = nil
64
- begin
65
- client, client_info = @server.accept
66
- rescue Exception => e
67
- @logger.log "Kinetic Test Server: EXCEPTION during accept!\n" +
68
- " #{e.inspect}\n" +
69
- " #{e.message}\n #{e.backtrace.join(" \n")}"
70
- next if client.nil?
71
- end
72
-
73
- next if client.nil?
186
+
187
+ # Service client connections (sequentially)
188
+ ClientProvider.each_client(@host, @port, @logger) do |client|
74
189
 
75
- @logger.log "Kinetic Test Server: Connected to #{client.inspect}"
76
190
  request = ''
77
- data = nil
78
191
  pdu = nil
79
- disconnect = false
80
-
81
- while !disconnect
82
- begin
83
- data = client.recv(1024)
84
- rescue IO::WaitReadable
85
- @logger.log("IO:WaitReadable");
86
- IO.select([client])
87
- retry
88
- rescue Exception => e
89
- @logger.logv "Kinetic Test Server: EXCEPTION during receive!\n" +
90
- " #{e.inspect}\n" +
91
- " #{e.message}\n #{e.backtrace.join(" \n")}"
92
- disconnect = true
93
- next
94
- end
192
+ connected = true
193
+ raw_proto = nil
95
194
 
96
- if (data.nil? || data.empty?)
97
- @logger.log "Kinetic Test Server: Client #{client.inspect} disconnected!"
98
- disconnect = true
99
- next
195
+ # Process requests while client available
196
+ while connected && (data = client.receive)
197
+ if data.nil? || data.empty?
198
+ connected = false
199
+ break
100
200
  end
101
201
 
202
+ # Append received data to request for processing
203
+ request += data
204
+
102
205
  # Incrementally parse PDU until complete
103
- if request[0] == KineticRuby::Proto::VERSION_PREFIX && request.length >= 9
104
- pdu ||= PDU.new(@Logger)
105
- pdu.update(request)
206
+ if PDU.valid_header? request
207
+ @logger.log 'Receiving a PDU...'
208
+ raw_pdu = request.bytes.map{|b| sprintf("%02X", b)}.join('')
209
+ @logger.log " request[#{request.length}]: #{raw_pdu}"
210
+ pdu ||= PDU.new(@logger)
211
+ if pdu.parse(request)
212
+ @logger.log "Received PDU successfully!"
213
+ else
214
+ @logger.log "Waiting on remainder of PDU..."
215
+ end
106
216
  end
107
217
 
218
+ # Handle raw protobuf.. for tests
219
+ if raw_proto || request.match(/^\n/)
220
+ @logger.log "Appears to be a standalone protobuf incoming..."
221
+ pdu = nil
222
+ raw_proto ||= []
223
+ raw_proto += request.bytes
224
+ @logger.log " protobuf: (#{raw_proto.length} bytes)"
225
+
108
226
  # Otherwise, handle custom test requests
109
- if pdu.nil?
227
+ elsif pdu.nil?
228
+ @logger.logv "Checking for custom request: '#{request}'"
110
229
  request_match = request.match(/^read\((\d+)\)/)
111
230
  if request_match
112
231
  len = request_match[1].to_i
113
232
  response = 'G'*len
114
- @logger.log "Kinetic Test Server: Responding to 'read(#{len})' w/ '#{response}'"
115
- client.write response
233
+ @logger.log "Responding to 'read(#{len})' w/ '#{response}'"
234
+ client.send response
116
235
  request = ''
236
+ pdu = nil
117
237
  elsif request =~ /^readProto()/
118
- response = @proto.test_encode
119
- @logger.log "Kinetic Test Server: Responding to 'read(#{len})' w/ dummy @protobuf (#{response.length} bytes)"
120
- client.write response
238
+ response = Proto.new(@logger).test_encode
239
+ @logger.log "Responding to 'read(#{len})' w/ dummy protobuf (#{response.length} bytes)"
240
+ client.send response
121
241
  request = ''
242
+ pdu = nil
243
+ elsif request.match(/^read/) && data.length < 7
244
+ @logger.log "no command match for request: '#{request}' (...yet)";
245
+ else
246
+ @logger.log "Unknown request! Aborting..."
247
+ request = ''
248
+ pdu = nil
249
+ connected = false
122
250
  end
123
251
  end
124
252
 
125
- @logger.log "Kinetic Test Server: Client #{client.inspect} disconnected!"
126
- client.close
127
- @logger.log "Kinetic Test Server: Client connection shutdown successfully"
128
- end
129
- end
130
- end
253
+ end #request service loop pass
254
+
255
+ @logger.log "Disconnecting from client..."
256
+
257
+ end #client connection
258
+
259
+ @logger.log "Client listener shutting down..."
260
+ end #worker thread
261
+
262
+ @logger.log "Listener shutdown successfully!"
263
+
131
264
  end
132
265
 
133
266
  def shutdown
134
- return if @server.nil?
135
- @logger.log "Kinetic Test Server: shutting down..."
267
+ return if @worker.nil?
268
+ @logger.log 'shutting down...'
136
269
  if @worker
137
270
  @worker.exit
138
- @worker.join(2)
271
+ @worker.join 2.0
139
272
  @worker = nil
140
273
  end
141
- if @server
142
- @server.close
143
- @server = nil
144
- end
145
- @logger.log "Kinetic Test Server: shutdown complete"
274
+ @logger.log 'shutdown complete'
146
275
  end
147
276
 
148
277
  end
@@ -1,4 +1,4 @@
1
1
  module KineticRuby
2
- VERSION = '0.6.0'
2
+ VERSION = '0.6.1'
3
3
  PROTOCOL_VERSION = 'v2.0.4'
4
4
  end
@@ -1,4 +1,4 @@
1
1
  module KineticRuby
2
- VERSION = '0.6.0'
2
+ VERSION = '0.6.1'
3
3
  PROTOCOL_VERSION = '<%= proto_ver %>'
4
4
  end
@@ -21,8 +21,11 @@ namespace :kinetic do
21
21
 
22
22
  desc "Shutdown Kinetic Test Server"
23
23
  task :shutdown do
24
- $kinetic_server.shutdown unless $kinetic_server.nil?
25
- $kinetic_server = nil
24
+ if $kinetic_server
25
+ $kinetic_server.shutdown
26
+ sleep 5.0
27
+ $kinetic_server = nil
28
+ end
26
29
  end
27
30
 
28
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kinetic-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-31 00:00:00.000000000 Z
11
+ date: 2014-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -64,6 +64,8 @@ files:
64
64
  - Rakefile
65
65
  - LICENSE
66
66
  - lib/kinetic-ruby.rb
67
+ - lib/kinetic_constants
68
+ - lib/kinetic_constants.rb
67
69
  - lib/kinetic_logger.rb
68
70
  - lib/kinetic_pdu.rb
69
71
  - lib/kinetic_proto.rb