ruby_skynet 0.5.0 → 0.6.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/Gemfile +3 -2
- data/Gemfile.lock +8 -4
- data/Rakefile +5 -5
- data/examples/echo_server.rb +0 -4
- data/lib/rails/generators/ruby_skynet/config/templates/ruby_skynet.yml +11 -2
- data/lib/ruby_skynet/client.rb +1 -1
- data/lib/ruby_skynet/common.rb +1 -0
- data/lib/ruby_skynet/connection.rb +2 -2
- data/lib/ruby_skynet/railties/ruby_skynet.rake +1 -1
- data/lib/ruby_skynet/ruby_skynet.rb +48 -1
- data/lib/ruby_skynet/server.rb +3 -3
- data/lib/ruby_skynet/service_registry.rb +248 -0
- data/lib/ruby_skynet/version.rb +1 -1
- data/lib/ruby_skynet.rb +9 -10
- data/test/client_test.rb +2 -0
- data/test/service_registry_test.rb +122 -0
- metadata +15 -20
- data/examples/e.rb +0 -0
- data/lib/ruby_skynet/doozer/client.rb +0 -209
- data/lib/ruby_skynet/doozer/exceptions.rb +0 -5
- data/lib/ruby_skynet/doozer/msg.pb.rb +0 -118
- data/lib/ruby_skynet/registry.rb +0 -375
- data/test/doozer_client_test.rb +0 -70
- data/test/registry_test.rb +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e4070e64ce70f32032c82eee9e6af0eaa94626c
|
4
|
+
data.tar.gz: 62ff2d291f403ac51406e17ead44a3f5feacd120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66559b704a0e6f1f73967e555d23c6f3eb975c58059324cb9f06944b4eff65ae22105ce1a28f4e7533d9cdb9a84d3f20de391dce860c2aa0a58bc935a28fbf88
|
7
|
+
data.tar.gz: 17d54811347c21ff8c20a174923ce96469e05ed56c9603abef0d1a3374eda8a80e1536cb3f35cbc07746ccfae7b9dac9afb126eb7630e900024fea863ae26687
|
data/Gemfile
CHANGED
@@ -2,18 +2,19 @@ source :rubygems
|
|
2
2
|
|
3
3
|
group :test do
|
4
4
|
gem "shoulda"
|
5
|
-
gem "mocha", :require => false
|
6
5
|
end
|
7
6
|
|
8
7
|
gem "rake"
|
9
8
|
gem "semantic_logger"
|
10
9
|
gem "resilient_socket"
|
10
|
+
# Doozer Client
|
11
|
+
gem "ruby_doozer"
|
11
12
|
# Thread Safe Hash and Array
|
12
13
|
gem "thread_safe"
|
14
|
+
# Connection pool
|
13
15
|
gem "gene_pool"
|
14
16
|
# For looking up Service entries in Doozer
|
15
17
|
gem "multi_json"
|
16
|
-
gem "ruby_protobuf"
|
17
18
|
# Wire format when communicating with services
|
18
19
|
gem "bson"
|
19
20
|
gem "bson_ext", :platform => :ruby
|
data/Gemfile.lock
CHANGED
@@ -4,8 +4,8 @@ GEM
|
|
4
4
|
activesupport (3.2.13)
|
5
5
|
i18n (= 0.6.1)
|
6
6
|
multi_json (~> 1.0)
|
7
|
-
atomic (1.0.
|
8
|
-
atomic (1.0.
|
7
|
+
atomic (1.0.2)
|
8
|
+
atomic (1.0.2-java)
|
9
9
|
bourne (1.4.0)
|
10
10
|
mocha (~> 0.13.2)
|
11
11
|
bson (1.8.3)
|
@@ -21,6 +21,11 @@ GEM
|
|
21
21
|
rake (10.0.3)
|
22
22
|
resilient_socket (0.4.0)
|
23
23
|
semantic_logger
|
24
|
+
ruby_doozer (0.4.0)
|
25
|
+
gene_pool
|
26
|
+
resilient_socket
|
27
|
+
ruby_protobuf
|
28
|
+
semantic_logger
|
24
29
|
ruby_protobuf (0.4.11)
|
25
30
|
semantic_logger (2.0.0)
|
26
31
|
sync_attr
|
@@ -44,11 +49,10 @@ DEPENDENCIES
|
|
44
49
|
bson
|
45
50
|
bson_ext
|
46
51
|
gene_pool
|
47
|
-
mocha
|
48
52
|
multi_json
|
49
53
|
rake
|
50
54
|
resilient_socket
|
51
|
-
|
55
|
+
ruby_doozer
|
52
56
|
semantic_logger
|
53
57
|
shoulda
|
54
58
|
thread_safe
|
data/Rakefile
CHANGED
@@ -24,12 +24,12 @@ 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'
|
28
|
-
spec.add_dependency 'resilient_socket'
|
27
|
+
spec.add_dependency 'semantic_logger', '>= 2.0.0'
|
28
|
+
spec.add_dependency 'resilient_socket', '>= 0.4.0'
|
29
29
|
spec.add_dependency 'multi_json', '>= 1.6.1'
|
30
|
-
spec.add_dependency 'bson'
|
31
|
-
spec.add_dependency '
|
32
|
-
spec.add_dependency 'gene_pool'
|
30
|
+
spec.add_dependency 'bson', '>= 1.5.2'
|
31
|
+
spec.add_dependency 'ruby_doozer', '>= 0.5.0'
|
32
|
+
spec.add_dependency 'gene_pool', '>= 1.3.0'
|
33
33
|
end
|
34
34
|
Gem::Package.build gemspec
|
35
35
|
end
|
data/examples/echo_server.rb
CHANGED
@@ -7,10 +7,6 @@ require 'ruby_skynet'
|
|
7
7
|
SemanticLogger::Logger.default_level = :trace
|
8
8
|
SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('echo_server.log')
|
9
9
|
|
10
|
-
# Specify Port and Hostname to listen for requests on
|
11
|
-
RubySkynet::Server.port = 2020
|
12
|
-
RubySkynet::Server.hostname = '127.0.0.1'
|
13
|
-
|
14
10
|
# Just echo back any parameters received when the echo method is called
|
15
11
|
class EchoService
|
16
12
|
include RubySkynet::Service
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# Ruby Skynet Client & Server Configuration Parameters
|
2
2
|
# :region [String]
|
3
|
-
# Region name to use for service
|
3
|
+
# Region name to use for service lookups
|
4
4
|
# Default: Rails.env
|
5
5
|
#
|
6
6
|
# :services_path [String]
|
7
|
-
# Path within to look for service implementations that will be loaded
|
7
|
+
# Path within which to look for service implementations that will be loaded
|
8
8
|
# when RubySkynet::Server.load_services is called
|
9
9
|
#
|
10
10
|
# :server_port [Integer]
|
@@ -53,6 +53,10 @@
|
|
53
53
|
# Randomly select a server from the list every time a connection
|
54
54
|
# is established, including during automatic connection recovery.
|
55
55
|
# Default: :ordered
|
56
|
+
#
|
57
|
+
# :pool_size [Integer]
|
58
|
+
# Maximum size of the connection pool to doozer
|
59
|
+
# Default: 10
|
56
60
|
defaults: &defaults
|
57
61
|
:services_path: app/services
|
58
62
|
:server_port: 2000
|
@@ -64,6 +68,11 @@ defaults: &defaults
|
|
64
68
|
:connect_retry_count: 10
|
65
69
|
:connect_retry_interval: 0.5
|
66
70
|
:server_selector: :random
|
71
|
+
# Doozer Connection Pool settings
|
72
|
+
:pool_size: 10
|
73
|
+
:pool_timeout: 30
|
74
|
+
:pool_warn_timeout: 2
|
75
|
+
:pool_idle_timeout: 600
|
67
76
|
|
68
77
|
development:
|
69
78
|
<<: *defaults
|
data/lib/ruby_skynet/client.rb
CHANGED
@@ -61,7 +61,7 @@ module RubySkynet
|
|
61
61
|
retries = 0
|
62
62
|
# If it cannot connect to a server, try a different server
|
63
63
|
begin
|
64
|
-
Connection.with_connection(
|
64
|
+
Connection.with_connection(::RubySkynet.services.server_for(@skynet_name, @version, @region), connection_params) do |connection|
|
65
65
|
connection.rpc_call(request_id, @skynet_name, method_name, parameters)
|
66
66
|
end
|
67
67
|
rescue ResilientSocket::ConnectionFailure => exc
|
data/lib/ruby_skynet/common.rb
CHANGED
@@ -5,7 +5,7 @@ require 'resilient_socket'
|
|
5
5
|
require 'sync_attr'
|
6
6
|
|
7
7
|
#
|
8
|
-
# RubySkynet Connection
|
8
|
+
# RubySkynet Client Connection
|
9
9
|
#
|
10
10
|
# Handles connecting to Skynet Servers as a host:port pair
|
11
11
|
#
|
@@ -237,7 +237,7 @@ module RubySkynet
|
|
237
237
|
end
|
238
238
|
|
239
239
|
# Cleanup corresponding connection pool when a server terminates
|
240
|
-
|
240
|
+
RubySkynet.services.on_server_removed(server) do
|
241
241
|
pool = @@connection_pools.delete(server)
|
242
242
|
# Cannot close all the connections since they could still be in use
|
243
243
|
pool.remove_idle(0) if pool
|
@@ -1,4 +1,7 @@
|
|
1
|
+
require 'sync_attr'
|
2
|
+
|
1
3
|
module RubySkynet
|
4
|
+
include SyncAttr
|
2
5
|
|
3
6
|
# Returns the default region for all Ruby Skynet Clients and Services
|
4
7
|
def self.region
|
@@ -42,6 +45,50 @@ module RubySkynet
|
|
42
45
|
@@local_ip_address = local_ip_address
|
43
46
|
end
|
44
47
|
|
48
|
+
# Returns the services registry consisting of service names
|
49
|
+
# and the hosts on which they are running
|
50
|
+
sync_cattr_reader :services do
|
51
|
+
ServiceRegistry.new(
|
52
|
+
:root_path => "/services",
|
53
|
+
:doozer => doozer_config
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Default doozer configuration
|
58
|
+
# To replace this default, set the config as follows:
|
59
|
+
# RubySkynet::Client.doozer_config = { .... }
|
60
|
+
#
|
61
|
+
# :servers [Array of String]
|
62
|
+
# Array of URL's of doozer servers to connect to with port numbers
|
63
|
+
# ['server1:2000', 'server2:2000']
|
64
|
+
#
|
65
|
+
# The second server will only be attempted once the first server
|
66
|
+
# cannot be connected to or has timed out on connect
|
67
|
+
# A read failure or timeout will not result in switching to the second
|
68
|
+
# server, only a connection failure or during an automatic reconnect
|
69
|
+
#
|
70
|
+
# :read_timeout [Float]
|
71
|
+
# Time in seconds to timeout on read
|
72
|
+
# Can be overridden by supplying a timeout in the read call
|
73
|
+
#
|
74
|
+
# :connect_timeout [Float]
|
75
|
+
# Time in seconds to timeout when trying to connect to the server
|
76
|
+
#
|
77
|
+
# :connect_retry_count [Fixnum]
|
78
|
+
# Number of times to retry connecting when a connection fails
|
79
|
+
#
|
80
|
+
# :connect_retry_interval [Float]
|
81
|
+
# Number of seconds between connection retry attempts after the first failed attempt
|
82
|
+
sync_cattr_accessor :doozer_config do
|
83
|
+
{
|
84
|
+
:servers => ['127.0.0.1:8046'],
|
85
|
+
:read_timeout => 5,
|
86
|
+
:connect_timeout => 3,
|
87
|
+
:connect_retry_interval => 1,
|
88
|
+
:connect_retry_count => 30
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
45
92
|
# Load the Encryption Configuration from a YAML file
|
46
93
|
# filename:
|
47
94
|
# Name of file to read.
|
@@ -61,7 +108,7 @@ module RubySkynet
|
|
61
108
|
RubySkynet.services_path = cfg.delete(:services_path) if [:services_path]
|
62
109
|
RubySkynet.server_port = cfg.delete(:server_port) if [:server_port]
|
63
110
|
RubySkynet.local_ip_address = cfg.delete(:local_ip_address) if [:local_ip_address]
|
64
|
-
RubySkynet
|
111
|
+
RubySkynet.doozer_config = cfg.delete(:doozer) if [:doozer]
|
65
112
|
|
66
113
|
cfg.each_pair {|k,v| RubySkynet::Server.logger.warn "Ignoring unknown RubySkynet config option #{k} => #{v}"}
|
67
114
|
end
|
data/lib/ruby_skynet/server.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'thread_safe'
|
2
2
|
|
3
3
|
#
|
4
4
|
# RubySkynet Server
|
@@ -206,13 +206,13 @@ module RubySkynet
|
|
206
206
|
# Registers a Service Class as being available at this server
|
207
207
|
def register_service(klass)
|
208
208
|
logger.debug "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
214
|
logger.debug "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
|
|
218
218
|
# Called for each message received from the client
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'sync_attr'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'thread_safe'
|
4
|
+
require 'gene_pool'
|
5
|
+
require 'resolv'
|
6
|
+
require 'ruby_doozer'
|
7
|
+
|
8
|
+
#
|
9
|
+
# RubySkynet Sevices Registry
|
10
|
+
#
|
11
|
+
# Based on the Skynet Services Registry, obtains and keeps up to date a list of
|
12
|
+
# all services and which servers they are available on.
|
13
|
+
#
|
14
|
+
module RubySkynet
|
15
|
+
class ServiceRegistry < RubyDoozer::Registry
|
16
|
+
include SyncAttr
|
17
|
+
include SemanticLogger::Loggable
|
18
|
+
|
19
|
+
IPV4_REG_EXP = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
|
20
|
+
|
21
|
+
# Returns [Integer] the score for the supplied ip_address
|
22
|
+
# Score currently ranges from 0 to 4 with 4 being the best score
|
23
|
+
# If the IP address does not match an IP v4 address a DNS lookup will
|
24
|
+
# be performed
|
25
|
+
def self.score_for_server(ip_address, local_ip_address)
|
26
|
+
score = 0
|
27
|
+
# Each matching element adds 1 to the score
|
28
|
+
# 192.168. 0. 0
|
29
|
+
# 1
|
30
|
+
# 1
|
31
|
+
# 1
|
32
|
+
# 1
|
33
|
+
server_match = IPV4_REG_EXP.match(ip_address) || IPV4_REG_EXP.match(Resolv::DNS.new.getaddress(ip_address).to_s)
|
34
|
+
if server_match
|
35
|
+
local_match = IPV4_REG_EXP.match(local_ip_address)
|
36
|
+
score = 0
|
37
|
+
(1..4).each do |i|
|
38
|
+
break if local_match[i].to_i != server_match[i].to_i
|
39
|
+
score += 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
score
|
43
|
+
end
|
44
|
+
|
45
|
+
# Create a service registry
|
46
|
+
# See: RubyDoozer::Registry for the parameters
|
47
|
+
def initialize(params)
|
48
|
+
super
|
49
|
+
|
50
|
+
# Registry has the following format
|
51
|
+
# Key: [String] 'name/version/region'
|
52
|
+
# Value: [Array<String>] 'host:port', 'host:port'
|
53
|
+
@registry = ThreadSafe::Hash.new
|
54
|
+
|
55
|
+
path = "#{@root_path}/**"
|
56
|
+
doozer_pool.with_connection do |doozer|
|
57
|
+
@current_revision = doozer.current_revision
|
58
|
+
# Fetch all the configuration information from Doozer and set the internal copy
|
59
|
+
doozer.walk(path, @current_revision) do |path, value|
|
60
|
+
service_info_changed(relative_path(path), value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Start monitoring thread
|
65
|
+
monitor_thread
|
66
|
+
|
67
|
+
# Register Callbacks
|
68
|
+
on_update {|path, value| service_info_changed(path, value) }
|
69
|
+
on_delete {|path, value| service_info_changed(path) }
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the Service Registry as a Hash
|
73
|
+
def to_h
|
74
|
+
@registry.dup
|
75
|
+
end
|
76
|
+
|
77
|
+
# Register the supplied service at this Skynet Server host and Port
|
78
|
+
def register_service(name, version, region, hostname, port)
|
79
|
+
config = {
|
80
|
+
"Config" => {
|
81
|
+
"UUID" => "#{hostname}:#{port}-#{$$}-#{name}-#{version}",
|
82
|
+
"Name" => name,
|
83
|
+
"Version" => version.to_s,
|
84
|
+
"Region" => region,
|
85
|
+
"ServiceAddr" => {
|
86
|
+
"IPAddress" => hostname,
|
87
|
+
"Port" => port,
|
88
|
+
"MaxPort" => port + 999
|
89
|
+
},
|
90
|
+
},
|
91
|
+
"Registered" => true
|
92
|
+
}
|
93
|
+
self["#{name}/#{version}/#{region}/#{hostname}/#{port}"] = MultiJson.encode(config)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Deregister the supplied service from the Registry
|
97
|
+
def deregister_service(name, version, region, hostname, port)
|
98
|
+
delete("#{name}/#{version}/#{region}/#{hostname}/#{port}")
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return a server that implements the specified service
|
102
|
+
def server_for(name, version='*', region='Development')
|
103
|
+
if servers = servers_for(name, version, region)
|
104
|
+
# Randomly select one of the servers offering the service
|
105
|
+
servers[rand(servers.size)]
|
106
|
+
else
|
107
|
+
msg = "No servers available for service: #{name} with version: #{version} in region: #{region}"
|
108
|
+
logger.warn msg
|
109
|
+
raise ServiceUnavailable.new(msg)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns [Array<String>] a list of servers implementing the requested service
|
114
|
+
def servers_for(name, version='*', region='Development')
|
115
|
+
if version == '*'
|
116
|
+
# Find the highest version for the named service in this region
|
117
|
+
version = -1
|
118
|
+
@registry.keys.each do |key|
|
119
|
+
if match = key.match(/#{name}\/(\d+)\/#{region}/)
|
120
|
+
ver = match[1].to_i
|
121
|
+
version = ver if ver > version
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
if server_infos = @registry["#{name}/#{version}/#{region}"]
|
126
|
+
server_infos.first.servers
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Invokes registered callbacks when a specific server is shutdown or terminates
|
131
|
+
# Not when a server de-registers itself
|
132
|
+
# The callback will only be called once and will need to be re-registered
|
133
|
+
# after being called if future callbacks are required for that server
|
134
|
+
def on_server_removed(server, &block)
|
135
|
+
((@on_server_removed_callbacks ||= ThreadSafe::Hash.new)[server] ||= ThreadSafe::Array.new) << block
|
136
|
+
end
|
137
|
+
|
138
|
+
############################
|
139
|
+
protected
|
140
|
+
|
141
|
+
# Service information changed in doozer, so update internal registry
|
142
|
+
def service_info_changed(path, value=nil)
|
143
|
+
# path: "TutorialService/1/Development/127.0.0.1/9000"
|
144
|
+
e = path.split('/')
|
145
|
+
|
146
|
+
# Key: [String] 'name/version/region'
|
147
|
+
key = "#{e[0]}/#{e[1]}/#{e[2]}"
|
148
|
+
hostname, port = e[3], e[4]
|
149
|
+
|
150
|
+
if value
|
151
|
+
entry = MultiJson.load(value)
|
152
|
+
if entry['Registered']
|
153
|
+
add_server(key, hostname, port)
|
154
|
+
else
|
155
|
+
# Service just de-registered
|
156
|
+
remove_server(key, hostname, port, false)
|
157
|
+
end
|
158
|
+
else
|
159
|
+
# Service has stopped and needs to be removed
|
160
|
+
remove_server(key, hostname, port, true)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# :score: [Integer] Score
|
165
|
+
# :servers: [Array<String>] 'host:port', 'host:port'
|
166
|
+
ServerInfo = Struct.new(:score, :servers )
|
167
|
+
|
168
|
+
# Format of the internal services registry
|
169
|
+
# key: [String] "<name>/<version>/<region>"
|
170
|
+
# value: [ServiceInfo, ServiceInfo]
|
171
|
+
# Sorted by highest score first
|
172
|
+
|
173
|
+
# Add the host to the registry based on it's score
|
174
|
+
def add_server(key, hostname, port)
|
175
|
+
server = "#{hostname}:#{port}"
|
176
|
+
logger.debug "#monitor Add/Update Service: #{key} => #{server.inspect}"
|
177
|
+
|
178
|
+
server_infos = (@registry[key] ||= ThreadSafe::Array.new)
|
179
|
+
|
180
|
+
# If already present, then nothing to do
|
181
|
+
server_info = server_infos.find{|si| si.servers.include?(server)}
|
182
|
+
return server_info if server_info
|
183
|
+
|
184
|
+
# Look for the same score with a different server
|
185
|
+
score = self.class.score_for_server(hostname, RubySkynet.local_ip_address)
|
186
|
+
if server_info = server_infos.find{|si| si.score == score}
|
187
|
+
server_info.servers << server
|
188
|
+
return server_info
|
189
|
+
end
|
190
|
+
|
191
|
+
# New score
|
192
|
+
servers = ThreadSafe::Array.new
|
193
|
+
servers << server
|
194
|
+
server_info = ServerInfo.new(score, servers)
|
195
|
+
|
196
|
+
# Insert into Array in order of score
|
197
|
+
if index = server_infos.find_index {|si| si.score <= score}
|
198
|
+
server_infos.insert(index, server_info)
|
199
|
+
else
|
200
|
+
server_infos << server_info
|
201
|
+
end
|
202
|
+
server_info
|
203
|
+
end
|
204
|
+
|
205
|
+
# Remove the host from the registry based
|
206
|
+
# Returns the server instance if it was removed
|
207
|
+
def remove_server(key, hostname, port, notify)
|
208
|
+
server = "#{hostname}:#{port}"
|
209
|
+
logger.debug "Remove Service: #{key} => #{server.inspect}"
|
210
|
+
server_info = nil
|
211
|
+
if server_infos = @registry[key]
|
212
|
+
server_infos.each do |si|
|
213
|
+
if si.servers.delete(server)
|
214
|
+
server_info = si
|
215
|
+
break
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Found server
|
220
|
+
if server_info
|
221
|
+
# Cleanup if no more servers in server list
|
222
|
+
server_infos.delete(server_info) if server_info.servers.size == 0
|
223
|
+
|
224
|
+
# Cleanup if no more server infos
|
225
|
+
@registry.delete(key) if server_infos.size == 0
|
226
|
+
|
227
|
+
server_removed(server) if notify
|
228
|
+
end
|
229
|
+
end
|
230
|
+
server_info
|
231
|
+
end
|
232
|
+
|
233
|
+
# Invoke any registered callbacks for the specific server
|
234
|
+
def server_removed(server)
|
235
|
+
if @on_server_removed_callbacks && (callbacks = @on_server_removed_callbacks.delete(server))
|
236
|
+
callbacks.each do |block|
|
237
|
+
begin
|
238
|
+
logger.info "Calling callback for server: #{server}"
|
239
|
+
block.call(server)
|
240
|
+
rescue Exception => exc
|
241
|
+
logger.error("Exception during a callback for server: #{server}", exc)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
data/lib/ruby_skynet/version.rb
CHANGED
data/lib/ruby_skynet.rb
CHANGED
@@ -2,17 +2,16 @@ require 'semantic_logger'
|
|
2
2
|
require 'ruby_skynet/exceptions'
|
3
3
|
require 'ruby_skynet/version'
|
4
4
|
require 'ruby_skynet/ruby_skynet'
|
5
|
+
require 'ruby_doozer'
|
6
|
+
|
5
7
|
module RubySkynet
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :Client, 'ruby_skynet/client'
|
14
|
-
autoload :Service, 'ruby_skynet/service'
|
15
|
-
autoload :Server, 'ruby_skynet/server'
|
8
|
+
autoload :Base, 'ruby_skynet/base'
|
9
|
+
autoload :Common, 'ruby_skynet/common'
|
10
|
+
autoload :Connection, 'ruby_skynet/connection'
|
11
|
+
autoload :Client, 'ruby_skynet/client'
|
12
|
+
autoload :Service, 'ruby_skynet/service'
|
13
|
+
autoload :Server, 'ruby_skynet/server'
|
14
|
+
autoload :ServiceRegistry, 'ruby_skynet/service_registry'
|
16
15
|
end
|
17
16
|
|
18
17
|
if defined?(Rails)
|
data/test/client_test.rb
CHANGED
@@ -58,6 +58,8 @@ class ClientTest < Test::Unit::TestCase
|
|
58
58
|
@region = 'ClientTest'
|
59
59
|
RubySkynet.region = @region
|
60
60
|
RubySkynet::Server.start
|
61
|
+
# Give doozer time to push out the presence of the service above
|
62
|
+
sleep 0.1
|
61
63
|
|
62
64
|
@service_name = 'ClientTestService'
|
63
65
|
@version = 1
|