ruby_skynet 2.0.0.rc1 → 2.0.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: bf65f91389e27d97e04be4be8a1ef49700bb245b
4
- data.tar.gz: 6b26fea72828375f49fff798c931744951747698
3
+ metadata.gz: f4b7ec3477060f1215627b808ee1f2962a4ad4ae
4
+ data.tar.gz: 4cf98cc577399f3d0521a84f5207322e436b4f3e
5
5
  SHA512:
6
- metadata.gz: 20a409544353b4634fde2fb83595e0998ef808383591ad08692bf5422d6bbf07995e1bf781b5a698ceeb7d1e1ec18d840eb8ef98b9f6939d27273a8c9324574c
7
- data.tar.gz: 8b049acd60bc68157ee6c632d7f44273fa366199c6bacbd6a0ef703c02d56190f1a1cec7471957452c453d07fd99a426efdba7842e6ca51383dc2abcaff6150a
6
+ metadata.gz: f6bc41df87ffbfae9c881ed44ba4932d5b46e79674c41db3e154cf357675e22ececd338856c2e2e7ab0db83f05484b83f3f067db76c9ac58b5b26925bbb5c1b3
7
+ data.tar.gz: 4f0356b9dae935ec70cef7b6db4ee7c98203f317a4c057814c42fcbeb7cf36a100cbaf7ccff214b0d1a5658ac590271542092fe7f4a6dc6543b06ecd0ce8e1cf
data/README.md CHANGED
@@ -37,7 +37,7 @@ class EchoService
37
37
  end
38
38
 
39
39
  # Start the server
40
- RubySkynet::Server.start
40
+ server = RubySkynet::Server.new
41
41
  ```
42
42
 
43
43
  Client to call the above Service
@@ -29,14 +29,18 @@ module RubySkynet
29
29
  begin
30
30
  require 'ruby_doozer'
31
31
  require 'ruby_skynet/doozer/service_registry'
32
+
33
+ # Shortcuts to loaded Registry classes
34
+ ServiceRegistry = RubySkynet::Doozer::ServiceRegistry
35
+ CachedRegistry = Doozer::CachedRegistry
36
+ Registry = Doozer::Registry
32
37
  rescue LoadError
33
- raise LoadError, "Load either the 'zookeeper' or 'ruby_doozer' gem prior to loading RubySkynet. 'zookeeper' is preferred"
38
+ require 'ruby_skynet/static_service_registry'
39
+
40
+ # Use Static Service Registry
41
+ ServiceRegistry = RubySkynet::StaticServiceRegistry
34
42
  end
35
43
 
36
- # Shortcuts to loaded Registry classes
37
- ServiceRegistry = RubySkynet::Doozer::ServiceRegistry
38
- CachedRegistry = Doozer::CachedRegistry
39
- Registry = Doozer::Registry
40
44
  end
41
45
  end
42
46
 
@@ -84,20 +84,14 @@ module RubySkynet
84
84
  # Skynet requires BSON RPC Calls to have the following format:
85
85
  # https://github.com/skynetservices/skynet/blob/master/protocol.md
86
86
  request_id = BSON::ObjectId.new.to_s
87
+
88
+ # Obtain list of servers implementing this service in order of priority
89
+ servers = ::RubySkynet.service_registry.servers_for(skynet_name, skynet_version, skynet_region)
90
+
87
91
  logger.tagged request_id do
88
92
  logger.benchmark_info "Called Skynet Service: #{skynet_name}.#{method_name}" do
89
- retries = 0
90
- # If it cannot connect to a server, try a different server
91
- begin
92
- Connection.with_connection(::RubySkynet.service_registry.server_for(skynet_name, skynet_version, skynet_region), connection_params) do |connection|
93
- connection.rpc_call(request_id, skynet_name, method_name, parameters)
94
- end
95
- rescue ResilientSocket::ConnectionFailure => exc
96
- if (retries < 3) && exc.cause.is_a?(Errno::ECONNREFUSED)
97
- retries += 1
98
- retry
99
- end
100
- # TODO rescue ServiceUnavailable retry x times until the service becomes available
93
+ Connection.with_connection(servers, connection_params) do |connection|
94
+ connection.rpc_call(request_id, skynet_name, method_name, parameters)
101
95
  end
102
96
  end
103
97
  end
@@ -1,5 +1,4 @@
1
1
  require 'bson'
2
- require 'gene_pool'
3
2
  require 'thread_safe'
4
3
  require 'resilient_socket'
5
4
  require 'sync_attr'
@@ -17,20 +16,6 @@ module RubySkynet
17
16
  # Returns the underlying socket being used by a Connection instance
18
17
  attr_reader :socket
19
18
 
20
- # Default Pool configuration
21
- sync_cattr_accessor :pool_config do
22
- {
23
- :pool_size => 30, # Maximum number of connections to any one server
24
- :warn_timeout => 2, # Log a warning if no connections are available after the :warn_timeout seconds
25
- :timeout => 10, # Raise a Timeout exception if no connections are available after the :timeout seconds
26
- :idle_timeout => 600, # Renew a connection if it has been idle for this period of time
27
- }
28
- end
29
-
30
- # For each server there is a connection pool keyed on the
31
- # server address: 'host:port'
32
- @@connection_pools = ThreadSafe::Hash.new
33
-
34
19
  # Returns a new RubySkynet connection to the server
35
20
  #
36
21
  # Parameters:
@@ -50,8 +35,8 @@ module RubySkynet
50
35
  # :connect_retry_interval [Float]
51
36
  # Number of seconds between connection retry attempts after the first failed attempt
52
37
  # Default: 0.5
53
- def initialize(server, params = {})
54
- self.logger = SemanticLogger["#{self.class.name} [#{server}]"]
38
+ def initialize(servers, params = {})
39
+ params = params.dup
55
40
 
56
41
  # User configurable options
57
42
  params[:read_timeout] ||= 60
@@ -95,8 +80,8 @@ module RubySkynet
95
80
  end
96
81
 
97
82
  # To prevent strange issues if user incorrectly supplies server names
98
- params.delete(:servers)
99
- params[:server] = server
83
+ params.delete(:server)
84
+ params[:servers] = servers
100
85
 
101
86
  @socket = ResilientSocket::TCPClient.new(params)
102
87
  end
@@ -209,44 +194,19 @@ module RubySkynet
209
194
 
210
195
  # Execute the supplied block with a connection from the pool
211
196
  def self.with_connection(server, params={}, &block)
212
- (@@connection_pools[server] ||= new_connection_pool(server, params)).with_connection(&block)
197
+ conn = nil
198
+ begin
199
+ conn = new(server, params)
200
+ block.call(conn)
201
+ ensure
202
+ conn.close if conn
203
+ end
213
204
  end
214
205
 
215
206
  def close
216
207
  @socket.close if @socket
217
208
  end
218
209
 
219
- ########################
220
- protected
221
-
222
- # Returns a new connection pool for the specified server
223
- def self.new_connection_pool(server, params={})
224
- # Connection pool configuration options
225
- config = pool_config.dup
226
-
227
- logger = SemanticLogger::Logger.new("#{self.class.name} [#{server}]")
228
-
229
- # Method to call to close idle connections
230
- config[:close_proc] = :close
231
- config[:logger] = logger
232
-
233
- pool = GenePool.new(pool_config) do
234
- new(server, params)
235
- end
236
-
237
- # Cleanup corresponding connection pool when a server terminates
238
- RubySkynet.service_registry.on_server_removed(server) do
239
- pool = @@connection_pools.delete(server)
240
- # Cannot close all the connections since they could still be in use
241
- pool.remove_idle(0) if pool
242
- #pool.close if pool
243
- logger.debug "Connection pool released"
244
- end
245
-
246
- pool
247
- end
248
-
249
210
  end
250
-
251
211
  end
252
212
 
@@ -1,6 +1,5 @@
1
1
  require 'semantic_logger'
2
2
  require 'thread_safe'
3
- require 'gene_pool'
4
3
  require 'resolv'
5
4
 
6
5
  #
@@ -62,18 +61,6 @@ module RubySkynet
62
61
  @registry.delete("#{name}/#{version}/#{region}/#{hostname}/#{port}")
63
62
  end
64
63
 
65
- # Return a server that implements the specified service
66
- def server_for(name, version='*', region=RubySkynet.region)
67
- if servers = servers_for(name, version, region)
68
- # Randomly select one of the servers offering the service
69
- servers[rand(servers.size)]
70
- else
71
- msg = "No servers available for service: #{name} with version: #{version} in region: #{region}"
72
- logger.warn msg
73
- raise ServiceUnavailable.new(msg)
74
- end
75
- end
76
-
77
64
  # Returns [Array<String>] a list of servers implementing the requested service
78
65
  def servers_for(name, version='*', region=RubySkynet.region)
79
66
  if version == '*'
@@ -86,9 +73,11 @@ module RubySkynet
86
73
  end
87
74
  end
88
75
  end
89
- if server_infos = @cache["#{name}/#{version}/#{region}"]
76
+ servers = if server_infos = @cache["#{name}/#{version}/#{region}"]
90
77
  server_infos.first.servers
91
78
  end
79
+ raise ServiceUnavailable.new("No servers available for service: #{name} with version: #{version} in region: #{region}") unless servers
80
+ servers
92
81
  end
93
82
 
94
83
  # Invokes registered callbacks when a specific server is shutdown or terminates
@@ -17,12 +17,14 @@ module RubySkynet #:nodoc:
17
17
 
18
18
  # Load RubySkynet Configuration once rails has started
19
19
  initializer 'ruby_skynet.initialize' do
20
- config_file = Rails.root.join("config", "ruby_skynet.yml")
21
- if config_file.file?
22
- ::RubySkynet.configure!(config_file, Rails.env)
23
- else
24
- puts "\nRuby Skynet config not found."
25
- puts "To generate one for the first time: rails generate ruby_skynet:config\n\n"
20
+ unless ::RubySkynet.configured?
21
+ config_file = Rails.root.join("config", "ruby_skynet.yml")
22
+ if config_file.file?
23
+ ::RubySkynet.configure!(config_file, Rails.env)
24
+ else
25
+ puts "\nRuby Skynet config not found."
26
+ puts "To generate one for the first time: rails generate ruby_skynet:config\n\n"
27
+ end
26
28
  end
27
29
  end
28
30
 
@@ -1,6 +1,6 @@
1
1
  namespace :ruby_skynet do
2
2
 
3
- desc "Start the Ruby Skynet Server.\n Rails Example: rake ruby_skynet:server\n Without Rails: SKYNET_ENV=production SKYNET_CONFIG=config/ruby_skynet rake ruby_skynet:server"
3
+ desc "Start the Ruby Skynet Server.\n Rails Example: rake ruby_skynet:server\n Without Rails: SKYNET_ENV=production SKYNET_CONFIG=config/ruby_skynet.yml rake ruby_skynet:server"
4
4
  task :server => :environment do
5
5
  # Configuration is automatically loaded when running under Rails
6
6
  # so skip it here under Rails
@@ -52,7 +52,7 @@ module RubySkynet
52
52
  # By default it connects to a local ZooKeeper instance
53
53
  # Use .configure! to supply a configuration file with any other settings
54
54
  sync_cattr_reader :service_registry do
55
- ServiceRegistry.new
55
+ ServiceRegistry.new(registry: {})
56
56
  end
57
57
 
58
58
  # Returns the current Registry Config information
@@ -60,7 +60,7 @@ module RubySkynet
60
60
  # By default it connects to a local ZooKeeper instance
61
61
  # Use .configure! to supply a configuration file with any other settings
62
62
  def self.registry_config
63
- @@config.dup if @@config && defined?(@@config)
63
+ @@config.dup if @@config
64
64
  end
65
65
 
66
66
  # Set the services registry
@@ -92,7 +92,7 @@ module RubySkynet
92
92
  RubySkynet.server_port = config.delete(:server_port) || 2000
93
93
  RubySkynet.local_ip_address = config.delete(:local_ip_address) || Common::local_ip_address
94
94
 
95
- # Extract just the zookeeper or doozer configuration element
95
+ # Extract the registry configuration element
96
96
  RubySkynet.service_registry = ServiceRegistry.new(
97
97
  :registry => config.delete(:registry)
98
98
  )
@@ -100,4 +100,8 @@ module RubySkynet
100
100
  config.each_pair {|k,v| warn "Ignoring unknown RubySkynet config option #{k} => #{v}"}
101
101
  end
102
102
 
103
+ # Returns [Boolean] whether the RubySkynet.configure! method has already been called
104
+ def self.configured?
105
+ !@@config.nil?
106
+ end
103
107
  end
@@ -0,0 +1,75 @@
1
+ require 'semantic_logger'
2
+ require 'thread_safe'
3
+
4
+ #
5
+ # RubySkynet Sevices Registry
6
+ #
7
+ # Loads a list of all services and which servers they are available on from a
8
+ # static YAML file
9
+ #
10
+ # Format of the YAML file
11
+ # key: [String] "<name>/<version>/<region>"
12
+ # value: [Array<String>] 'host:port', 'host:port'
13
+ #
14
+ module RubySkynet
15
+ class StaticServiceRegistry
16
+ include SemanticLogger::Loggable
17
+
18
+ # Create a service registry
19
+ def initialize(params = {})
20
+ @services = params[:registry]
21
+ raise "Missing :registry in config that must list the availables services" unless @services
22
+ end
23
+
24
+ # Returns the Service Registry as a Hash
25
+ def to_h
26
+ @services.dup
27
+ end
28
+
29
+ # Register the supplied service at this Skynet Server host and Port
30
+ # Returns the UUID for the service that was created
31
+ def register_service(name, version, region, hostname, port)
32
+ server = "#{hostname}:#{port}"
33
+ key = "#{name}/#{version}/#{region}"
34
+ (@services[key] ||= []) << server
35
+ key
36
+ end
37
+
38
+ # Deregister the supplied service from the Registry
39
+ def deregister_service(name, version, region, hostname, port)
40
+ server = "#{hostname}:#{port}"
41
+ key = "#{name}/#{version}/#{region}"
42
+ if servers = @services[key]
43
+ servers.delete_if {|s| s == server}
44
+ @services.delete(key) if servers.count == 0
45
+ end
46
+ key
47
+ end
48
+
49
+ # Returns [Array<String>] a list of servers implementing the requested service
50
+ def servers_for(name, version='*', region=RubySkynet.region)
51
+ if version == '*'
52
+ # Find the highest version for the named service in this region
53
+ version = -1
54
+ @services.keys.each do |key|
55
+ if match = key.match(/#{name}\/(\d+)\/#{region}/)
56
+ ver = match[1].to_i
57
+ version = ver if ver > version
58
+ end
59
+ end
60
+ end
61
+ servers = @services["#{name}/#{version}/#{region}"]
62
+ raise ServiceUnavailable.new("No servers available for service: #{name} with version: #{version} in region: #{region}") unless servers
63
+ servers
64
+ end
65
+
66
+ # Invokes registered callbacks when a specific server is shutdown or terminates
67
+ # Not when a server de-registers itself
68
+ # The callback will only be called once and will need to be re-registered
69
+ # after being called if future callbacks are required for that server
70
+ def on_server_removed(server, &block)
71
+ #nop
72
+ end
73
+
74
+ end
75
+ end
@@ -1,3 +1,3 @@
1
1
  module RubySkynet #:nodoc
2
- VERSION = "2.0.0.rc1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require 'semantic_logger'
2
2
  require 'thread_safe'
3
- require 'gene_pool'
4
3
  require 'resolv'
5
4
 
6
5
  #
@@ -76,18 +75,6 @@ module RubySkynet
76
75
  uuid
77
76
  end
78
77
 
79
- # Return a server that implements the specified service
80
- def server_for(name, version='*', region=RubySkynet.region)
81
- if servers = servers_for(name, version, region)
82
- # Randomly select one of the servers offering the service
83
- servers[rand(servers.size)]
84
- else
85
- msg = "No servers available for service: #{name} with version: #{version} in region: #{region}"
86
- logger.warn msg
87
- raise ServiceUnavailable.new(msg)
88
- end
89
- end
90
-
91
78
  # Returns [Array<String>] a list of servers implementing the requested service
92
79
  def servers_for(name, version='*', region=RubySkynet.region)
93
80
  if version == '*'
@@ -100,9 +87,11 @@ module RubySkynet
100
87
  end
101
88
  end
102
89
  end
103
- if server_infos = @cache["#{name}/#{version}/#{region}"]
90
+ servers = if server_infos = @cache["#{name}/#{version}/#{region}"]
104
91
  server_infos.first.servers
105
92
  end
93
+ raise ServiceUnavailable.new("No servers available for service: #{name} with version: #{version} in region: #{region}") unless servers
94
+ servers
106
95
  end
107
96
 
108
97
  # Invokes registered callbacks when a specific server is shutdown or terminates
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: 2.0.0.rc1
4
+ version: 2.0.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-11-14 00:00:00.000000000 Z
11
+ date: 2014-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic_logger
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.1.0
19
+ version: 2.6.1
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.1.0
26
+ version: 2.6.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: resilient_socket
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.5.0
41
- - !ruby/object:Gem::Dependency
42
- name: gene_pool
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: 1.3.0
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: 1.3.0
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: sync_attr
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -70,14 +56,14 @@ dependencies:
70
56
  name: bson
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - ~>
59
+ - - '>='
74
60
  - !ruby/object:Gem::Version
75
61
  version: 2.0.0.rc3
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - ~>
66
+ - - '>='
81
67
  - !ruby/object:Gem::Version
82
68
  version: 2.0.0.rc3
83
69
  - !ruby/object:Gem::Dependency
@@ -113,6 +99,7 @@ files:
113
99
  - lib/ruby_skynet/ruby_skynet.rb
114
100
  - lib/ruby_skynet/server.rb
115
101
  - lib/ruby_skynet/service.rb
102
+ - lib/ruby_skynet/static_service_registry.rb
116
103
  - lib/ruby_skynet/version.rb
117
104
  - lib/ruby_skynet/zookeeper/cached_registry.rb
118
105
  - lib/ruby_skynet/zookeeper/extensions/java_base.rb
@@ -141,12 +128,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
128
  version: '0'
142
129
  required_rubygems_version: !ruby/object:Gem::Requirement
143
130
  requirements:
144
- - - '>'
131
+ - - '>='
145
132
  - !ruby/object:Gem::Version
146
- version: 1.3.1
133
+ version: '0'
147
134
  requirements: []
148
135
  rubyforge_project:
149
- rubygems_version: 2.0.3
136
+ rubygems_version: 2.1.11
150
137
  signing_key:
151
138
  specification_version: 4
152
139
  summary: Skynet Ruby Client