kinetic-ruby 0.6.0 → 0.6.1

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.
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