ruby_skynet 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|