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 +4 -4
- data/README.md +1 -1
- data/lib/ruby_skynet.rb +9 -5
- data/lib/ruby_skynet/client.rb +6 -12
- data/lib/ruby_skynet/connection.rb +11 -51
- data/lib/ruby_skynet/doozer/service_registry.rb +3 -14
- data/lib/ruby_skynet/railtie.rb +8 -6
- data/lib/ruby_skynet/railties/ruby_skynet.rake +1 -1
- data/lib/ruby_skynet/ruby_skynet.rb +7 -3
- data/lib/ruby_skynet/static_service_registry.rb +75 -0
- data/lib/ruby_skynet/version.rb +1 -1
- data/lib/ruby_skynet/zookeeper/service_registry.rb +3 -14
- metadata +10 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4b7ec3477060f1215627b808ee1f2962a4ad4ae
|
4
|
+
data.tar.gz: 4cf98cc577399f3d0521a84f5207322e436b4f3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6bc41df87ffbfae9c881ed44ba4932d5b46e79674c41db3e154cf357675e22ececd338856c2e2e7ab0db83f05484b83f3f067db76c9ac58b5b26925bbb5c1b3
|
7
|
+
data.tar.gz: 4f0356b9dae935ec70cef7b6db4ee7c98203f317a4c057814c42fcbeb7cf36a100cbaf7ccff214b0d1a5658ac590271542092fe7f4a6dc6543b06ecd0ce8e1cf
|
data/README.md
CHANGED
data/lib/ruby_skynet.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/ruby_skynet/client.rb
CHANGED
@@ -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
|
-
|
90
|
-
|
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(
|
54
|
-
|
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(:
|
99
|
-
params[:
|
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
|
-
|
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
|
data/lib/ruby_skynet/railtie.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
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
|
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
|
data/lib/ruby_skynet/version.rb
CHANGED
@@ -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
|
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:
|
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
|
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
|
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:
|
133
|
+
version: '0'
|
147
134
|
requirements: []
|
148
135
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.
|
136
|
+
rubygems_version: 2.1.11
|
150
137
|
signing_key:
|
151
138
|
specification_version: 4
|
152
139
|
summary: Skynet Ruby Client
|