ruby_skynet 0.6.0 → 0.7.0

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: 5e4070e64ce70f32032c82eee9e6af0eaa94626c
4
- data.tar.gz: 62ff2d291f403ac51406e17ead44a3f5feacd120
3
+ metadata.gz: 09c9a8e2a436c89fd46211dc103f0b55946fbfc2
4
+ data.tar.gz: e2683cdb8fae60e831c7793fca87e4f1ae573095
5
5
  SHA512:
6
- metadata.gz: 66559b704a0e6f1f73967e555d23c6f3eb975c58059324cb9f06944b4eff65ae22105ce1a28f4e7533d9cdb9a84d3f20de391dce860c2aa0a58bc935a28fbf88
7
- data.tar.gz: 17d54811347c21ff8c20a174923ce96469e05ed56c9603abef0d1a3374eda8a80e1536cb3f35cbc07746ccfae7b9dac9afb126eb7630e900024fea863ae26687
6
+ metadata.gz: 87a5e433d14d3c986c44472f0c19baeebd54a87362e071478d046238217470072fae4712af21ada8b16e771c326c44aa5a7b69ac96b124a0f3bab7e7994f2226
7
+ data.tar.gz: 5baff9cf4822187512543ef599f7e6842a5dab2a95744da5a55461a9d711c820f738018b8783672b8f3da12d1903a66c70bfc955395217d2df83db8f8ac5fb15
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ group :test do
5
5
  end
6
6
 
7
7
  gem "rake"
8
- gem "semantic_logger"
8
+ gem "semantic_logger", ">= 2.1"
9
9
  gem "resilient_socket"
10
10
  # Doozer Client
11
11
  gem "ruby_doozer"
data/Gemfile.lock CHANGED
@@ -21,7 +21,7 @@ GEM
21
21
  rake (10.0.3)
22
22
  resilient_socket (0.4.0)
23
23
  semantic_logger
24
- ruby_doozer (0.4.0)
24
+ ruby_doozer (0.5.0)
25
25
  gene_pool
26
26
  resilient_socket
27
27
  ruby_protobuf
data/Rakefile CHANGED
@@ -24,11 +24,11 @@ task :gem do |t|
24
24
  spec.files = FileList["./**/*"].exclude(/\.gem$/, /\.log$/,/nbproject/).map{|f| f.sub(/^\.\//, '')}
25
25
  spec.license = "Apache License V2.0"
26
26
  spec.has_rdoc = true
27
- spec.add_dependency 'semantic_logger', '>= 2.0.0'
28
- spec.add_dependency 'resilient_socket', '>= 0.4.0'
27
+ spec.add_dependency 'semantic_logger', '>= 2.1.0'
28
+ spec.add_dependency 'resilient_socket', '>= 0.5.0'
29
29
  spec.add_dependency 'multi_json', '>= 1.6.1'
30
30
  spec.add_dependency 'bson', '>= 1.5.2'
31
- spec.add_dependency 'ruby_doozer', '>= 0.5.0'
31
+ spec.add_dependency 'ruby_doozer', '>= 0.6.0'
32
32
  spec.add_dependency 'gene_pool', '>= 1.3.0'
33
33
  end
34
34
  Gem::Package.build gemspec
@@ -3,8 +3,12 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
3
  require 'rubygems'
4
4
  require 'ruby_skynet'
5
5
 
6
- SemanticLogger::Logger.default_level = :trace
7
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('echo_client.log')
6
+ SemanticLogger.default_level = :info
7
+ SemanticLogger.add_appender(STDOUT)
8
8
 
9
- client = RubySkynet::Client.new('EchoService')
10
- p client.call('echo', :hello => 'world')
9
+ class Echo < RubySkynet::Client
10
+ self.skynet_name = "EchoService"
11
+ end
12
+
13
+ client = Echo.new
14
+ p client.echo(:hello => 'world')
@@ -3,18 +3,20 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
3
  require 'rubygems'
4
4
  require 'ruby_skynet'
5
5
 
6
- # Log trace information to a log file
7
- SemanticLogger::Logger.default_level = :trace
8
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('echo_server.log')
6
+ SemanticLogger.default_level = :info
7
+ SemanticLogger.add_appender(STDOUT)
9
8
 
10
9
  # Just echo back any parameters received when the echo method is called
11
10
  class EchoService
12
11
  include RubySkynet::Service
13
12
 
13
+ skynet_name = "JoeService"
14
+
14
15
  # Methods implemented by this service
15
16
  # Must take a Hash as input
16
17
  # Must Return a Hash response or nil for no response
17
18
  def echo(params)
19
+ params['echo'] = true
18
20
  params
19
21
  end
20
22
  end
@@ -25,4 +27,3 @@ RubySkynet::Server.start
25
27
  puts "Press enter to shutdown server"
26
28
  gets
27
29
 
28
- RubySkynet::Server.stop
@@ -7,24 +7,6 @@ module RubySkynet
7
7
  base.extend ClassMethods
8
8
  base.class_eval do
9
9
  include SemanticLogger::Loggable
10
- include InstanceMethods
11
- end
12
- end
13
-
14
- module InstanceMethods
15
- # Implement methods that call the remote Service
16
- def method_missing(method, *args, &block)
17
- result = ruby_skynet_client.call(method, *args)
18
- # Define the method if the call was successful and no-one else already
19
- # created the method
20
- if result[:exception].nil? && !self.class.method_defined?(method)
21
- self.class.send(:define_method, method) {|*args| ruby_skynet_client.call(method, *args)}
22
- end
23
- result
24
- end
25
-
26
- def ruby_skynet_client
27
- @ruby_skynet_client ||= RubySkynet::Client.new(self.class.skynet_name, self.class.skynet_version || '*', self.class.skynet_region)
28
10
  end
29
11
  end
30
12
 
@@ -8,6 +8,17 @@ require 'bson'
8
8
  #
9
9
  module RubySkynet
10
10
  class Client
11
+ include Base
12
+
13
+ attr_reader :skynet_name, :skynet_version, :skynet_region
14
+
15
+ # Version of the Skynet service to use
16
+ # By default it will connect to the latest version
17
+ # Default: '*'
18
+ def self.skynet_version
19
+ @skynet_version ||= '*'
20
+ end
21
+
11
22
  # Returns a new RubySkynet Client for the named service
12
23
  #
13
24
  # Calls to an instance of the Client are thread-safe and can be called
@@ -15,29 +26,45 @@ module RubySkynet
15
26
  #
16
27
  # Parameters:
17
28
  # :skynet_name
29
+ # Only required when creating instance of RubySkynet::Client directly
30
+ # Otherwise it defaults to the name of the class
18
31
  # Name of the service to look for and connect to on Skynet
19
32
  #
20
- # :version
33
+ # :skynet_version
21
34
  # Optional version number of the service in Skynet
22
35
  # Default: '*' being the latest version of the service
23
36
  #
24
- # :region
37
+ # :skynet_region
25
38
  # Optional region for this service in Skynet
26
- # Default: 'Development'
39
+ # Default: RubySkynet.region
40
+ #
41
+ # Example using Client class
42
+ #
43
+ # require 'ruby_skynet'
44
+ # SemanticLogger.default_level = :info
45
+ # SemanticLogger.add_appender(STDOUT)
27
46
  #
28
- # Example
47
+ # class EchoService < RubySkynet::Client
48
+ # end
49
+ #
50
+ # echo_service = EchoService.new
51
+ # p echo_service.echo(:value => 5)
52
+ #
53
+ # Example using Ruby Client directly
29
54
  #
30
55
  # require 'ruby_skynet'
31
- # SemanticLogger.default_level = :trace
32
- # SemanticLogger.appenders << SemanticLogger::Appender::File(STDOUT)
56
+ # SemanticLogger.default_level = :info
57
+ # SemanticLogger.add_appender(STDOUT)
33
58
  #
34
59
  # tutorial_service = RubySkynet::Client.new('TutorialService')
35
60
  # p tutorial_service.call('Add', :value => 5)
36
- def initialize(skynet_name, version='*', region='Development')
37
- @skynet_name = skynet_name
38
- @logger = SemanticLogger::Logger.new("#{self.class.name}: #{skynet_name}/#{version}/#{region}")
39
- @version = version
40
- @region = region
61
+ def initialize(skynet_name=self.class.skynet_name, skynet_version=self.class.skynet_version, skynet_region=self.class.skynet_region)
62
+ @skynet_name = skynet_name
63
+ @skynet_version = skynet_version
64
+ @skynet_region = skynet_region
65
+ self.logger = SemanticLogger["#{self.class.name}: #{@skynet_name}/#{@skynet_version}/#{@skynet_region}"]
66
+
67
+ raise "skynet_name is mandatory when using RubySkynet::Client directly" if @skynet_name == RubySkynet::Client.name
41
68
  end
42
69
 
43
70
  # Performs a synchronous call to the Skynet Service
@@ -56,13 +83,13 @@ module RubySkynet
56
83
  # Skynet requires BSON RPC Calls to have the following format:
57
84
  # https://github.com/skynetservices/skynet/blob/master/protocol.md
58
85
  request_id = BSON::ObjectId.new.to_s
59
- @logger.tagged request_id do
60
- @logger.benchmark_info "Called Skynet Service: #{@skynet_name}.#{method_name}" do
86
+ logger.tagged request_id do
87
+ logger.benchmark_info "Called Skynet Service: #{skynet_name}.#{method_name}" do
61
88
  retries = 0
62
89
  # If it cannot connect to a server, try a different server
63
90
  begin
64
- Connection.with_connection(::RubySkynet.services.server_for(@skynet_name, @version, @region), connection_params) do |connection|
65
- connection.rpc_call(request_id, @skynet_name, method_name, parameters)
91
+ Connection.with_connection(::RubySkynet.services.server_for(skynet_name, skynet_version, skynet_region), connection_params) do |connection|
92
+ connection.rpc_call(request_id, skynet_name, method_name, parameters)
66
93
  end
67
94
  rescue ResilientSocket::ConnectionFailure => exc
68
95
  if (retries < 3) && exc.cause.is_a?(Errno::ECONNREFUSED)
@@ -75,5 +102,19 @@ module RubySkynet
75
102
  end
76
103
  end
77
104
 
105
+ # Implement methods that call the remote Service
106
+ def method_missing(method, *args, &block)
107
+ result = call(method, *args)
108
+
109
+ # #TODO if Service returns method undefined, call super
110
+ #
111
+ # Define the method if the call was successful and no other thread has
112
+ # already created the method
113
+ if result[:exception].nil? && !self.class.method_defined?(method)
114
+ self.class.send(:define_method, method) {|*args| call(method, *args)}
115
+ end
116
+ result
117
+ end
118
+
78
119
  end
79
120
  end
@@ -12,6 +12,7 @@ require 'sync_attr'
12
12
  module RubySkynet
13
13
  class Connection
14
14
  include SyncAttr
15
+ include SemanticLogger::Loggable
15
16
 
16
17
  # Returns the underlying socket being used by a Connection instance
17
18
  attr_reader :socket
@@ -26,11 +27,6 @@ module RubySkynet
26
27
  }
27
28
  end
28
29
 
29
- # Logging instance for the connection pool
30
- sync_cattr_reader :logger do
31
- SemanticLogger::Logger.new(self)
32
- end
33
-
34
30
  # For each server there is a connection pool keyed on the
35
31
  # server address: 'host:port'
36
32
  @@connection_pools = ThreadSafe::Hash.new
@@ -55,7 +51,7 @@ module RubySkynet
55
51
  # Number of seconds between connection retry attempts after the first failed attempt
56
52
  # Default: 0.5
57
53
  def initialize(server, params = {})
58
- @logger = SemanticLogger::Logger.new("#{self.class.name}: #{server}")
54
+ self.logger = SemanticLogger["#{self.class.name} [#{server}]"]
59
55
 
60
56
  # User configurable options
61
57
  params[:read_timeout] ||= 60
@@ -71,7 +67,7 @@ module RubySkynet
71
67
  # Reset user_data on each connection
72
68
  socket.user_data = {
73
69
  :seq => 0,
74
- :logger => @logger
70
+ :logger => logger
75
71
  }
76
72
 
77
73
  # Receive Service Handshake
@@ -81,9 +77,9 @@ module RubySkynet
81
77
  #
82
78
  # ClientID string
83
79
  # ClientID is a UUID that is used by the client to identify itself in RPC requests.
84
- @logger.debug "Waiting for Service Handshake"
80
+ logger.debug "Waiting for Service Handshake"
85
81
  service_handshake = Common.read_bson_document(socket)
86
- @logger.trace 'Service Handshake', service_handshake
82
+ logger.trace 'Service Handshake', service_handshake
87
83
 
88
84
  # #TODO When a reconnect returns registered == false need to throw an exception
89
85
  # so that this host connection is not used
@@ -93,8 +89,8 @@ module RubySkynet
93
89
 
94
90
  # Send blank ClientHandshake
95
91
  client_handshake = { 'clientid' => client_id }
96
- @logger.debug "Sending Client Handshake"
97
- @logger.trace 'Client Handshake', client_handshake
92
+ logger.debug "Sending Client Handshake"
93
+ logger.trace 'Client Handshake', client_handshake
98
94
  socket.write(BSON.serialize(client_handshake).to_s)
99
95
  end
100
96
 
@@ -123,91 +119,92 @@ module RubySkynet
123
119
  # Raises RubySkynet::ProtocolError
124
120
  # Raises RubySkynet::SkynetException
125
121
  def rpc_call(request_id, skynet_name, method_name, parameters, idempotent=false)
126
- retry_count = 0
127
- header = nil
128
- response = nil
129
-
130
- socket.retry_on_connection_failure do |socket|
131
- header = {
132
- 'servicemethod' => "#{skynet_name}.Forward",
133
- 'seq' => socket.user_data[:seq]
134
- }
122
+ logger.benchmark_info "Called #{skynet_name}.#{method_name}" do
123
+ retry_count = 0
124
+ header = nil
125
+ response = nil
126
+ socket.retry_on_connection_failure do |socket|
127
+ header = {
128
+ 'servicemethod' => "#{skynet_name}.Forward",
129
+ 'seq' => socket.user_data[:seq]
130
+ }
135
131
 
136
- @logger.debug "Sending Header"
137
- @logger.trace 'Header', header
138
- socket.write(BSON.serialize(header).to_s)
139
-
140
- # The parameters are placed in the request object in BSON serialized form
141
- request = {
142
- 'clientid' => socket.user_data[:client_id],
143
- 'in' => BSON::Binary.new(BSON.serialize(parameters).to_s),
144
- 'method' => method_name.to_s,
145
- 'requestinfo' => {
146
- 'requestid' => request_id,
147
- # Increment retry count to indicate that the request may have been tried previously
148
- 'retrycount' => retry_count,
149
- # TODO: this should be forwarded along in case of services also
150
- # being a client and calling additional services. If empty it will
151
- # be stuffed with connecting address
152
- 'originaddress' => ''
132
+ logger.debug "Sending Header"
133
+ logger.trace 'Header', header
134
+ socket.write(BSON.serialize(header).to_s)
135
+
136
+ # The parameters are placed in the request object in BSON serialized form
137
+ request = {
138
+ 'clientid' => socket.user_data[:client_id],
139
+ 'in' => BSON::Binary.new(BSON.serialize(parameters).to_s),
140
+ 'method' => method_name.to_s,
141
+ 'requestinfo' => {
142
+ 'requestid' => request_id,
143
+ # Increment retry count to indicate that the request may have been tried previously
144
+ 'retrycount' => retry_count,
145
+ # TODO: this should be forwarded along in case of services also
146
+ # being a client and calling additional services. If empty it will
147
+ # be stuffed with connecting address
148
+ 'originaddress' => ''
149
+ }
153
150
  }
154
- }
155
151
 
156
- @logger.debug "Sending Request"
157
- @logger.trace 'Request', request
158
- @logger.trace 'Parameters:', parameters
159
- socket.write(BSON.serialize(request).to_s)
152
+ logger.debug "Sending Request"
153
+ logger.trace 'Request', request
154
+ logger.trace 'Parameters:', parameters
155
+ socket.write(BSON.serialize(request).to_s)
156
+
157
+ # Since Send does not affect state on the server we can also retry reads
158
+ if idempotent
159
+ logger.debug "Reading header from server"
160
+ header = Common.read_bson_document(socket)
161
+ logger.debug 'Response Header', header
162
+
163
+ # Read the BSON response document
164
+ logger.debug "Reading response from server"
165
+ response = Common.read_bson_document(socket)
166
+ logger.trace 'Response', response
167
+ end
168
+ end
160
169
 
161
- # Since Send does not affect state on the server we can also retry reads
162
- if idempotent
163
- @logger.debug "Reading header from server"
170
+ # Perform the read outside the retry block since a successful write
171
+ # means that the servers state may have been changed
172
+ unless idempotent
173
+ # Read header first as a separate BSON document
174
+ logger.debug "Reading header from server"
164
175
  header = Common.read_bson_document(socket)
165
- @logger.debug 'Response Header', header
176
+ logger.debug 'Response Header', header
166
177
 
167
178
  # Read the BSON response document
168
- @logger.debug "Reading response from server"
179
+ logger.debug "Reading response from server"
169
180
  response = Common.read_bson_document(socket)
170
- @logger.trace 'Response', response
181
+ logger.trace 'Response', response
171
182
  end
172
- end
173
183
 
174
- # Perform the read outside the retry block since a successful write
175
- # means that the servers state may have been changed
176
- unless idempotent
177
- # Read header first as a separate BSON document
178
- @logger.debug "Reading header from server"
179
- header = Common.read_bson_document(socket)
180
- @logger.debug 'Response Header', header
181
-
182
- # Read the BSON response document
183
- @logger.debug "Reading response from server"
184
- response = Common.read_bson_document(socket)
185
- @logger.trace 'Response', response
186
- end
187
-
188
- # Ensure the sequence number in the response header matches the
189
- # sequence number sent in the request
190
- seq_no = header['seq']
191
- if seq_no != socket.user_data[:seq]
192
- raise ProtocolError.new("Incorrect Response received, expected seq=#{socket.user_data[:seq]}, received: #{header.inspect}")
193
- end
184
+ # Ensure the sequence number in the response header matches the
185
+ # sequence number sent in the request
186
+ seq_no = header['seq']
187
+ if seq_no != socket.user_data[:seq]
188
+ raise ProtocolError.new("Incorrect Response received, expected seq=#{socket.user_data[:seq]}, received: #{header.inspect}")
189
+ end
194
190
 
195
- # Increment Sequence number only on successful response
196
- socket.user_data[:seq] += 1
191
+ # Increment Sequence number only on successful response
192
+ socket.user_data[:seq] += 1
197
193
 
198
- # If an error is returned from Skynet raise a Skynet exception
199
- error = header['error']
200
- raise SkynetException.new(error) if error.to_s.length > 0
194
+ # If an error is returned from Skynet raise a Skynet exception
195
+ error = header['error']
196
+ raise SkynetException.new(error) if error.to_s.length > 0
201
197
 
202
- # If an error is returned from the service raise a Service exception
203
- error = response['error']
204
- raise ServiceException.new(error) if error.to_s.length > 0
198
+ # If an error is returned from the service raise a Service exception
199
+ error = response['error']
200
+ raise ServiceException.new(error) if error.to_s.length > 0
205
201
 
206
- # Return Value
207
- # The return value is inside the response object, it's a byte array of it's own and needs to be deserialized
208
- result = BSON.deserialize(response['out'])
209
- @logger.trace 'Return Value', result
210
- result
202
+ # Return Value
203
+ # The return value is inside the response object, it's a byte array of it's own and needs to be deserialized
204
+ result = BSON.deserialize(response['out'])
205
+ logger.trace 'Return Value', result
206
+ result
207
+ end
211
208
  end
212
209
 
213
210
  # Execute the supplied block with a connection from the pool
@@ -227,10 +224,11 @@ module RubySkynet
227
224
  # Connection pool configuration options
228
225
  config = pool_config.dup
229
226
 
227
+ logger = SemanticLogger::Logger.new("#{self.class.name} [#{server}]")
228
+
230
229
  # Method to call to close idle connections
231
230
  config[:close_proc] = :close
232
231
  config[:logger] = logger
233
- config[:name] = "Connection pool for #{server}"
234
232
 
235
233
  pool = GenePool.new(pool_config) do
236
234
  new(server, params)
@@ -242,7 +240,7 @@ module RubySkynet
242
240
  # Cannot close all the connections since they could still be in use
243
241
  pool.remove_idle(0) if pool
244
242
  #pool.close if pool
245
- logger.debug "Connection pool for server:#{server} has been released"
243
+ logger.debug "Connection pool released"
246
244
  end
247
245
 
248
246
  pool
@@ -205,13 +205,13 @@ module RubySkynet
205
205
 
206
206
  # Registers a Service Class as being available at this server
207
207
  def register_service(klass)
208
- logger.debug "Registering Service: #{klass.name} with name: #{klass.skynet_name}"
208
+ logger.info "Registering Service: #{klass.name} with name: #{klass.skynet_name}"
209
209
  ::RubySkynet.services.register_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
210
210
  end
211
211
 
212
212
  # De-register service from this server
213
213
  def deregister_service(klass)
214
- logger.debug "De-registering Service: #{klass.name} with name: #{klass.skynet_name}"
214
+ logger.info "De-registering Service: #{klass.name} with name: #{klass.skynet_name}"
215
215
  ::RubySkynet.services.deregister_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
216
216
  end
217
217
 
@@ -99,7 +99,7 @@ module RubySkynet
99
99
  end
100
100
 
101
101
  # Return a server that implements the specified service
102
- def server_for(name, version='*', region='Development')
102
+ def server_for(name, version='*', region=RubySkynet.region)
103
103
  if servers = servers_for(name, version, region)
104
104
  # Randomly select one of the servers offering the service
105
105
  servers[rand(servers.size)]
@@ -111,7 +111,7 @@ module RubySkynet
111
111
  end
112
112
 
113
113
  # Returns [Array<String>] a list of servers implementing the requested service
114
- def servers_for(name, version='*', region='Development')
114
+ def servers_for(name, version='*', region=RubySkynet.region)
115
115
  if version == '*'
116
116
  # Find the highest version for the named service in this region
117
117
  version = -1
@@ -173,7 +173,6 @@ module RubySkynet
173
173
  # Add the host to the registry based on it's score
174
174
  def add_server(key, hostname, port)
175
175
  server = "#{hostname}:#{port}"
176
- logger.debug "#monitor Add/Update Service: #{key} => #{server.inspect}"
177
176
 
178
177
  server_infos = (@registry[key] ||= ThreadSafe::Array.new)
179
178
 
@@ -183,6 +182,7 @@ module RubySkynet
183
182
 
184
183
  # Look for the same score with a different server
185
184
  score = self.class.score_for_server(hostname, RubySkynet.local_ip_address)
185
+ logger.info "Service: #{key} now running at #{server} with score #{score}"
186
186
  if server_info = server_infos.find{|si| si.score == score}
187
187
  server_info.servers << server
188
188
  return server_info
@@ -206,7 +206,7 @@ module RubySkynet
206
206
  # Returns the server instance if it was removed
207
207
  def remove_server(key, hostname, port, notify)
208
208
  server = "#{hostname}:#{port}"
209
- logger.debug "Remove Service: #{key} => #{server.inspect}"
209
+ logger.info "Service: #{key} stopped running at #{server}"
210
210
  server_info = nil
211
211
  if server_infos = @registry[key]
212
212
  server_infos.each do |si|
@@ -235,7 +235,7 @@ module RubySkynet
235
235
  if @on_server_removed_callbacks && (callbacks = @on_server_removed_callbacks.delete(server))
236
236
  callbacks.each do |block|
237
237
  begin
238
- logger.info "Calling callback for server: #{server}"
238
+ logger.debug "Calling callback for server: #{server}"
239
239
  block.call(server)
240
240
  rescue Exception => exc
241
241
  logger.error("Exception during a callback for server: #{server}", exc)
@@ -1,3 +1,3 @@
1
1
  module RubySkynet #:nodoc
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/test/client_test.rb CHANGED
@@ -8,10 +8,8 @@ require 'shoulda'
8
8
  require 'ruby_skynet'
9
9
 
10
10
  # Register an appender if one is not already registered
11
- if SemanticLogger::Logger.appenders.size == 0
12
- SemanticLogger::Logger.default_level = :trace
13
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('test.log')
14
- end
11
+ SemanticLogger.default_level = :trace
12
+ SemanticLogger.add_appender('test.log') if SemanticLogger.appenders.size == 0
15
13
 
16
14
  class ClientTestService
17
15
  include RubySkynet::Service
@@ -38,17 +36,21 @@ class ClientTestService
38
36
 
39
37
  end
40
38
 
39
+ # Test Client Class
40
+ class ClientTestServiceClient < RubySkynet::Client
41
+ end
42
+
41
43
  # Unit Test for ResilientSocket::TCPClient
42
44
  class ClientTest < Test::Unit::TestCase
43
45
  context RubySkynet::Client do
44
46
 
45
47
  context "without server" do
46
- should "raise exception when cannot reach server after 5 retries" do
48
+ should "raise exception when not registered" do
47
49
  exception = assert_raise RubySkynet::ServiceUnavailable do
48
- client = RubySkynet::Client.new('SomeService')
50
+ client = RubySkynet::Client.new('SomeService','*','ClientTest')
49
51
  client.call(:test, :hello => 'there')
50
52
  end
51
- assert_match /No servers available for service: SomeService with version: \* in region: Development/, exception.message
53
+ assert_match /No servers available for service: SomeService with version: \* in region: ClientTest/, exception.message
52
54
  end
53
55
 
54
56
  end
@@ -90,8 +92,29 @@ class ClientTest < Test::Unit::TestCase
90
92
  end
91
93
  assert_match /Timedout after #{@read_timeout} seconds trying to read/, exception.message
92
94
  end
95
+ end
96
+
97
+ context "using client class" do
98
+ setup do
99
+ @client = ClientTestServiceClient.new("ClientTestService")
100
+ end
101
+
102
+ should "successfully send and receive data" do
103
+ reply = @client.test1('some' => 'parameters')
104
+ assert_equal 'test1', reply['result']
105
+ end
93
106
 
107
+ should "timeout on receive" do
108
+ request = { 'duration' => @read_timeout + 0.5}
109
+
110
+ exception = assert_raise ResilientSocket::ReadTimeout do
111
+ # Read 4 bytes from server
112
+ @client.sleep(request, :read_timeout => @read_timeout)
113
+ end
114
+ assert_match /Timedout after #{@read_timeout} seconds trying to read/, exception.message
115
+ end
94
116
  end
117
+
95
118
  end
96
119
  end
97
120
  end
@@ -7,10 +7,8 @@ require 'shoulda'
7
7
  require 'ruby_skynet'
8
8
 
9
9
  # Register an appender if one is not already registered
10
- if SemanticLogger::Logger.appenders.size == 0
11
- SemanticLogger::Logger.default_level = :trace
12
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('test.log')
13
- end
10
+ SemanticLogger.default_level = :trace
11
+ SemanticLogger.add_appender('test.log') if SemanticLogger.appenders.size == 0
14
12
 
15
13
  # Unit Test
16
14
  class ServiceRegistryTest < Test::Unit::TestCase
@@ -23,12 +21,17 @@ class ServiceRegistryTest < Test::Unit::TestCase
23
21
  @hostname = '127.0.0.1'
24
22
  @port = 2100
25
23
  @service_key = "/services/#{@service_name}/#{@version}/#{@region}/#{@hostname}/#{@port}"
24
+ RubySkynet.local_ip_address = @hostname
25
+ end
26
+
27
+ teardown do
28
+ RubySkynet.local_ip_address = nil
26
29
  end
27
30
 
28
31
  context "without a registered service" do
29
32
  should "not be in doozer" do
30
33
  RubySkynet.services.send(:doozer_pool).with_connection do |doozer|
31
- assert_equal '', doozer[@service_key]
34
+ assert_equal nil, doozer[@service_key]
32
35
  end
33
36
  end
34
37
  end
@@ -36,12 +39,14 @@ class ServiceRegistryTest < Test::Unit::TestCase
36
39
  context "with a registered service" do
37
40
  setup do
38
41
  RubySkynet.services.register_service(@service_name, @version, @region, @hostname, @port)
42
+ RubySkynet.services.register_service(@service_name, @version, @region+'BLAH', @hostname, @port)
39
43
  # Allow time for doozer callback that service was registered
40
44
  sleep 0.1
41
45
  end
42
46
 
43
47
  teardown do
44
48
  RubySkynet.services.deregister_service(@service_name, @version, @region, @hostname, @port)
49
+ RubySkynet.services.deregister_service(@service_name, @version, @region+'BLAH', @hostname, @port)
45
50
  # Allow time for doozer callback that service was deregistered
46
51
  sleep 0.1
47
52
  # No servers should be in the local registry
@@ -78,9 +83,10 @@ class ServiceRegistryTest < Test::Unit::TestCase
78
83
 
79
84
  should "using * version match" do
80
85
  assert servers = RubySkynet.services.servers_for(@service_name, '*', @region)
81
- assert_equal 3, servers.size, RubySkynet.services.to_h.to_s
82
- assert_equal "#{@hostname}:#{@port}", servers.first
83
- assert_equal "#{@hostname}:#{@port+3}", servers.last
86
+ assert_equal 3, servers.size, servers
87
+ assert_equal true, servers.include?("#{@hostname}:#{@port}"), servers
88
+ assert_equal true, servers.include?("#{@hostname}:#{@port+1}"), servers
89
+ assert_equal true, servers.include?("#{@hostname}:#{@port+3}"), servers
84
90
  end
85
91
  end
86
92
 
data/test/service_test.rb CHANGED
@@ -7,10 +7,8 @@ require 'shoulda'
7
7
  require 'ruby_skynet'
8
8
 
9
9
  # Register an appender if one is not already registered
10
- if SemanticLogger::Logger.appenders.size == 0
11
- SemanticLogger::Logger.default_level = :trace
12
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('test.log')
13
- end
10
+ SemanticLogger.default_level = :trace
11
+ SemanticLogger.add_appender('test.log') if SemanticLogger.appenders.size == 0
14
12
 
15
13
  class TestService
16
14
  include RubySkynet::Service
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_skynet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-01 00:00:00.000000000 Z
11
+ date: 2013-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic_logger
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0
19
+ version: 2.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.0
26
+ version: 2.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: resilient_socket
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '>='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.0
33
+ version: 0.5.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.4.0
40
+ version: 0.5.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: multi_json
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - '>='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.5.0
75
+ version: 0.6.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '>='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.5.0
82
+ version: 0.6.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: gene_pool
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -124,7 +124,6 @@ files:
124
124
  - lib/ruby_skynet/service_registry.rb
125
125
  - lib/ruby_skynet/version.rb
126
126
  - test.sh
127
- - test/base_test.rb
128
127
  - test/client_test.rb
129
128
  - test/service_registry_test.rb
130
129
  - test/service_test.rb
data/test/base_test.rb DELETED
@@ -1,89 +0,0 @@
1
- # Allow test to be run in-place without requiring a gem install
2
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
- $LOAD_PATH.unshift File.dirname(__FILE__)
4
-
5
- require 'rubygems'
6
- require 'test/unit'
7
- require 'shoulda'
8
- require 'ruby_skynet'
9
-
10
- # Register an appender if one is not already registered
11
- if SemanticLogger::Logger.appenders.size == 0
12
- SemanticLogger::Logger.default_level = :debug
13
- SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('test.log')
14
- end
15
-
16
- # Service implementation
17
- class BaseTestService
18
- include RubySkynet::Service
19
-
20
- # Methods implemented by this service
21
- # Must take a Hash as input
22
- # Must Return a Hash response or nil for no response
23
- def test1(params)
24
- { 'result' => 'test1' }
25
- end
26
-
27
- def sleep(params)
28
- Kernel.sleep params['duration'] || 1
29
- { 'result' => 'sleep' }
30
- end
31
-
32
- def fail(params)
33
- if params['attempt'].to_i >= 2
34
- { 'result' => 'fail' }
35
- else
36
- nil
37
- end
38
- end
39
-
40
- end
41
-
42
- # Service Client
43
- class BaseTestServiceClient
44
- include RubySkynet::Base
45
-
46
- # Override Name registered in skynet to match server above
47
- self.skynet_name = 'BaseTestService'
48
- end
49
-
50
- # Unit Test
51
- class BaseTest < Test::Unit::TestCase
52
- context RubySkynet::Base do
53
-
54
- context "with server" do
55
- setup do
56
- RubySkynet.region = @region
57
- RubySkynet::Server.start
58
-
59
- @read_timeout = 3.0
60
- end
61
-
62
- teardown do
63
- RubySkynet::Server.stop
64
- end
65
-
66
- context "with client connection" do
67
- setup do
68
- @client = BaseTestServiceClient.new
69
- end
70
-
71
- should "successfully send and receive data" do
72
- reply = @client.test1('some' => 'parameters')
73
- assert_equal 'test1', reply['result']
74
- end
75
-
76
- should "timeout on receive" do
77
- request = { 'duration' => @read_timeout + 0.5}
78
-
79
- exception = assert_raise ResilientSocket::ReadTimeout do
80
- # Read 4 bytes from server
81
- @client.sleep(request, :read_timeout => @read_timeout)
82
- end
83
- assert_match /Timedout after #{@read_timeout} seconds trying to read/, exception.message
84
- end
85
-
86
- end
87
- end
88
- end
89
- end