ruby_skynet 0.8.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -2
- data/Gemfile.lock +22 -16
- data/README.md +13 -9
- data/Rakefile +1 -2
- data/lib/rails/generators/ruby_skynet/config/templates/ruby_skynet.yml +25 -21
- data/lib/ruby_skynet/client.rb +1 -1
- data/lib/ruby_skynet/connection.rb +1 -1
- data/lib/ruby_skynet/railties/ruby_skynet.rake +6 -1
- data/lib/ruby_skynet/registry.rb +17 -0
- data/lib/ruby_skynet/ruby_skynet.rb +47 -48
- data/lib/ruby_skynet/server.rb +13 -13
- data/lib/ruby_skynet/service.rb +1 -1
- data/lib/ruby_skynet/service_registry.rb +48 -55
- data/lib/ruby_skynet/version.rb +1 -1
- data/lib/ruby_skynet/zookeeper/cached_registry.rb +75 -0
- data/lib/ruby_skynet/zookeeper/extensions/java_base.rb +27 -0
- data/lib/ruby_skynet/zookeeper/json/deserializer.rb +64 -0
- data/lib/ruby_skynet/zookeeper/json/serializer.rb +57 -0
- data/lib/ruby_skynet/zookeeper/registry.rb +510 -0
- data/lib/ruby_skynet/zookeeper.rb +11 -0
- data/lib/ruby_skynet.rb +2 -1
- data/test/client_test.rb +1 -1
- data/test/service_registry_test.rb +21 -35
- data/test/zookeeper_registry_test.rb +200 -0
- metadata +16 -23
- data/test.sh +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71af05d7950d049061c39abe50a23dd1fe02a51d
|
4
|
+
data.tar.gz: b312ef155c2aacea545f434d4d9e38348bc94ac5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 240897f81ded9f668da49ed7280b378bbe92d17e819e9c795a47affd7e6996a972d61168f4b9c104b8a21b4a01937523d5104661590ab82005de8fa1f39e6c38
|
7
|
+
data.tar.gz: 423409dbf2038a5723438004d451a28b4493edd85eadbf6cd239a0190c11b508ac56eb36be29872be28c2c6b057c31f7e2ba099912153b5cebd0384daf46a517
|
data/Gemfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
group :test do
|
4
4
|
gem "shoulda"
|
@@ -9,11 +9,13 @@ gem "semantic_logger", ">= 2.1"
|
|
9
9
|
gem "resilient_socket"
|
10
10
|
# Doozer Client
|
11
11
|
gem "ruby_doozer"
|
12
|
+
# Zookeeper Client
|
13
|
+
gem "zookeeper"
|
12
14
|
# Thread Safe Hash and Array
|
13
15
|
gem "thread_safe"
|
14
16
|
# Connection pool
|
15
17
|
gem "gene_pool"
|
16
|
-
# For looking up Service entries in
|
18
|
+
# For looking up Service entries in Service Registry
|
17
19
|
gem "multi_json"
|
18
20
|
# Wire format when communicating with services
|
19
21
|
gem "bson"
|
data/Gemfile.lock
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
GEM
|
2
|
-
remote:
|
2
|
+
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (
|
5
|
-
i18n (
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
bson (~> 1.8.6)
|
4
|
+
activesupport (4.0.0)
|
5
|
+
i18n (~> 0.6, >= 0.6.4)
|
6
|
+
minitest (~> 4.2)
|
7
|
+
multi_json (~> 1.3)
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
tzinfo (~> 0.3.37)
|
10
|
+
atomic (1.1.10-java)
|
11
|
+
bson (1.9.0-java)
|
13
12
|
gene_pool (1.3.0)
|
14
|
-
i18n (0.6.
|
15
|
-
|
16
|
-
|
13
|
+
i18n (0.6.4)
|
14
|
+
minitest (4.7.5)
|
15
|
+
multi_json (1.7.7)
|
16
|
+
rake (10.1.0)
|
17
17
|
resilient_socket (0.5.0)
|
18
18
|
semantic_logger (>= 2.1)
|
19
19
|
ruby_doozer (0.7.1)
|
@@ -30,16 +30,21 @@ GEM
|
|
30
30
|
shoulda (3.5.0)
|
31
31
|
shoulda-context (~> 1.0, >= 1.0.1)
|
32
32
|
shoulda-matchers (>= 1.4.1, < 3.0)
|
33
|
-
shoulda-context (1.1.
|
34
|
-
shoulda-matchers (2.
|
33
|
+
shoulda-context (1.1.4)
|
34
|
+
shoulda-matchers (2.2.0)
|
35
35
|
activesupport (>= 3.0.0)
|
36
|
+
slyphon-log4j (1.2.15)
|
37
|
+
slyphon-zookeeper_jar (3.3.5-java)
|
36
38
|
sync_attr (1.0.0)
|
37
39
|
thread_safe (0.1.0)
|
38
40
|
atomic
|
41
|
+
tzinfo (0.3.37)
|
42
|
+
zookeeper (1.4.4-java)
|
43
|
+
slyphon-log4j (= 1.2.15)
|
44
|
+
slyphon-zookeeper_jar (= 3.3.5)
|
39
45
|
|
40
46
|
PLATFORMS
|
41
47
|
java
|
42
|
-
ruby
|
43
48
|
|
44
49
|
DEPENDENCIES
|
45
50
|
bson
|
@@ -52,3 +57,4 @@ DEPENDENCIES
|
|
52
57
|
semantic_logger (>= 2.1)
|
53
58
|
shoulda
|
54
59
|
thread_safe
|
60
|
+
zookeeper
|
data/README.md
CHANGED
@@ -74,23 +74,27 @@ client = Echo.new
|
|
74
74
|
p client.echo(:hello => 'world')
|
75
75
|
```
|
76
76
|
|
77
|
-
### Architecture
|
78
|
-
|
79
|
-
ruby_skynet implements its own doozer client which has been tested against
|
80
|
-
the doozer fork: https://github.com/4ad/doozerd.
|
81
|
-
The doozer client uses the active [ruby_protobuf](https://github.com/macks/ruby-protobuf)
|
82
|
-
project for marshaling data for communicating with doozer
|
83
|
-
|
84
77
|
### Dependencies
|
85
78
|
|
86
|
-
- Ruby
|
79
|
+
- Ruby 1.8.7, Ruby 1.9.3, Ruby 2.0.0, or JRuby 1.6.3 (or higher)
|
87
80
|
- [SemanticLogger](http://github.com/ClarityServices/semantic_logger)
|
88
81
|
- [ResilientSocket](https://github.com/ClarityServices/resilient_socket)
|
89
|
-
- [ruby_protobuf](https://github.com/macks/ruby-protobuf)
|
90
82
|
- [multi_json](https://github.com/intridea/multi_json)
|
91
83
|
|
84
|
+
One of the following Service Registry Implementations
|
85
|
+
- ZooKeeper Ruby Client [zk](https://github.com/slyphon/zk)
|
86
|
+
- [ruby_doozer](http://github.com/skynetservices/ruby_doozer)
|
87
|
+
|
92
88
|
### Install
|
93
89
|
|
90
|
+
Installing for a ZooKeeper centralized service registry - Recommended
|
91
|
+
|
92
|
+
gem install zk
|
93
|
+
gem install ruby_skynet
|
94
|
+
|
95
|
+
OR, Installing for a Doozer centralized service registry
|
96
|
+
|
97
|
+
gem install ruby_doozer
|
94
98
|
gem install ruby_skynet
|
95
99
|
|
96
100
|
Development
|
data/Rakefile
CHANGED
@@ -28,9 +28,8 @@ task :gem do |t|
|
|
28
28
|
spec.add_dependency 'resilient_socket', '>= 0.5.0'
|
29
29
|
spec.add_dependency 'bson', '>= 1.5.2'
|
30
30
|
spec.add_dependency 'gene_pool', '>= 1.3.0'
|
31
|
+
spec.add_dependency 'zookeeper', '>= 1.4.4'
|
31
32
|
spec.add_dependency 'sync_attr', '>= 1.0.0'
|
32
|
-
spec.add_dependency 'ruby_doozer', '>= 0.7.0'
|
33
|
-
spec.add_dependency 'gene_pool', '>= 1.3.0'
|
34
33
|
end
|
35
34
|
Gem::Package.build gemspec
|
36
35
|
end
|
@@ -18,24 +18,20 @@
|
|
18
18
|
# by remote Skynet clients
|
19
19
|
# Note: Must be an IP address, not the hostname
|
20
20
|
#
|
21
|
-
#
|
22
|
-
# :
|
21
|
+
# Registry settings
|
22
|
+
# :registry
|
23
23
|
# :servers [Array of String]
|
24
24
|
# Array of URL's of doozer servers to connect to with port numbers
|
25
25
|
# ['server1:2000', 'server2:2000']
|
26
26
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# A read failure or timeout will not result in switching to the second
|
30
|
-
# server, only a connection failure or during an automatic reconnect
|
27
|
+
# :connect_timeout [Float]
|
28
|
+
# Time in seconds to timeout when trying to connect to the server
|
31
29
|
#
|
30
|
+
# Additional Doozer configuration options
|
32
31
|
# :read_timeout [Float]
|
33
32
|
# Time in seconds to timeout on read
|
34
33
|
# Can be overridden by supplying a timeout in the read call
|
35
34
|
#
|
36
|
-
# :connect_timeout [Float]
|
37
|
-
# Time in seconds to timeout when trying to connect to the server
|
38
|
-
#
|
39
35
|
# :connect_retry_count [Fixnum]
|
40
36
|
# Number of times to retry connecting when a connection fails
|
41
37
|
#
|
@@ -49,6 +45,10 @@
|
|
49
45
|
# Select a server in the order supplied in the array, with the first
|
50
46
|
# having the highest priority. The second server will only be connected
|
51
47
|
# to if the first server is unreachable
|
48
|
+
# The second server will only be attempted once the first server
|
49
|
+
# cannot be connected to or has timed out on connect
|
50
|
+
# A read failure or timeout will not result in switching to the second
|
51
|
+
# server, only a connection failure or during an automatic reconnect
|
52
52
|
# :random
|
53
53
|
# Randomly select a server from the list every time a connection
|
54
54
|
# is established, including during automatic connection recovery.
|
@@ -60,19 +60,23 @@
|
|
60
60
|
defaults: &defaults
|
61
61
|
:services_path: app/services
|
62
62
|
:server_port: 2000
|
63
|
-
|
63
|
+
|
64
|
+
# Registry Settings
|
65
|
+
:registry:
|
64
66
|
:servers:
|
65
|
-
- 127.0.0.1:
|
66
|
-
:
|
67
|
-
|
68
|
-
|
69
|
-
:
|
70
|
-
:
|
71
|
-
|
72
|
-
:
|
73
|
-
|
74
|
-
:
|
75
|
-
:
|
67
|
+
- 127.0.0.1:2181
|
68
|
+
:connect_timeout: 3
|
69
|
+
|
70
|
+
# Additional Doozer configuration settings
|
71
|
+
# :read_timeout: 5
|
72
|
+
# :connect_retry_count: 10
|
73
|
+
# :connect_retry_interval: 0.5
|
74
|
+
# :server_selector: :random
|
75
|
+
# # Doozer Connection Pool settings
|
76
|
+
# :pool_size: 10
|
77
|
+
# :pool_timeout: 30
|
78
|
+
# :pool_warn_timeout: 2
|
79
|
+
# :pool_idle_timeout: 600
|
76
80
|
|
77
81
|
development:
|
78
82
|
<<: *defaults
|
data/lib/ruby_skynet/client.rb
CHANGED
@@ -88,7 +88,7 @@ module RubySkynet
|
|
88
88
|
retries = 0
|
89
89
|
# If it cannot connect to a server, try a different server
|
90
90
|
begin
|
91
|
-
Connection.with_connection(::RubySkynet.
|
91
|
+
Connection.with_connection(::RubySkynet.service_registry.server_for(skynet_name, skynet_version, skynet_region), connection_params) do |connection|
|
92
92
|
connection.rpc_call(request_id, skynet_name, method_name, parameters)
|
93
93
|
end
|
94
94
|
rescue ResilientSocket::ConnectionFailure => exc
|
@@ -235,7 +235,7 @@ module RubySkynet
|
|
235
235
|
end
|
236
236
|
|
237
237
|
# Cleanup corresponding connection pool when a server terminates
|
238
|
-
RubySkynet.
|
238
|
+
RubySkynet.service_registry.on_server_removed(server) do
|
239
239
|
pool = @@connection_pools.delete(server)
|
240
240
|
# Cannot close all the connections since they could still be in use
|
241
241
|
pool.remove_idle(0) if pool
|
@@ -15,13 +15,18 @@ namespace :ruby_skynet do
|
|
15
15
|
RubySkynet.configure!(cfg_file, environment)
|
16
16
|
end
|
17
17
|
|
18
|
-
# Connect to
|
18
|
+
# Connect to services registry
|
19
19
|
RubySkynet.services
|
20
20
|
|
21
21
|
RubySkynet::Server.load_services
|
22
22
|
|
23
23
|
# Start the server
|
24
24
|
RubySkynet::Server.start
|
25
|
+
|
26
|
+
at_exit do
|
27
|
+
RubySkynet::Server.stop
|
28
|
+
end
|
29
|
+
|
25
30
|
RubySkynet::Server.wait_until_server_stops
|
26
31
|
end
|
27
32
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Define RubySkynet::Registry based on whether the ZooKeeper or Doozer gem is present
|
2
|
+
module RubySkynet
|
3
|
+
begin
|
4
|
+
require 'zookeeper'
|
5
|
+
require 'zookeeper/client'
|
6
|
+
# Monkey-patch so that the Zookeeper JRuby code can handle nil values in Zookeeper
|
7
|
+
require 'ruby_skynet/zookeeper/extensions/java_base' if defined?(::JRUBY_VERSION)
|
8
|
+
Registry = RubySkynet::Zookeeper::Registry
|
9
|
+
rescue LoadError
|
10
|
+
begin
|
11
|
+
require 'ruby_doozer'
|
12
|
+
rescue LoadError
|
13
|
+
raise LoadError, "Must gem install either 'zookeeper' or 'ruby_doozer'. 'zookeeper' is recommended"
|
14
|
+
end
|
15
|
+
Registry = Doozer::Registry
|
16
|
+
end
|
17
|
+
end
|
@@ -45,51 +45,28 @@ module RubySkynet
|
|
45
45
|
@@local_ip_address = local_ip_address
|
46
46
|
end
|
47
47
|
|
48
|
-
# Returns the services registry
|
48
|
+
# Returns the services registry which holds the service names
|
49
49
|
# and the hosts on which they are running
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
)
|
50
|
+
#
|
51
|
+
# By default it connects to a local ZooKeeper instance
|
52
|
+
# Use .configure! to supply a configuration file with any other settings
|
53
|
+
sync_cattr_reader :service_registry do
|
54
|
+
ServiceRegistry.new(:root => '/services')
|
55
55
|
end
|
56
56
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
|
61
|
-
|
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
|
-
}
|
57
|
+
# Set the services registry
|
58
|
+
# It is recommended to call RubySkynet.configure! rather than calling this
|
59
|
+
# method directly
|
60
|
+
def self.service_registry=(service_registry)
|
61
|
+
@@service_registry = service_registry
|
90
62
|
end
|
91
63
|
|
92
|
-
#
|
64
|
+
# DEPRECATED - Use RubySkynet.service_registry
|
65
|
+
def self.services
|
66
|
+
@@service_registry
|
67
|
+
end
|
68
|
+
|
69
|
+
# Load the Configuration information from a YAML file
|
93
70
|
# filename:
|
94
71
|
# Name of file to read.
|
95
72
|
# Mandatory for non-Rails apps
|
@@ -101,16 +78,38 @@ module RubySkynet
|
|
101
78
|
config_file = filename.nil? ? Rails.root.join('config', 'ruby_skynet.yml') : Pathname.new(filename)
|
102
79
|
raise "ruby_skynet config not found. Create a config file at: config/ruby_skynet.yml" unless config_file.file?
|
103
80
|
|
104
|
-
|
105
|
-
raise("Environment #{Rails.env} not defined in config/ruby_skynet.yml") unless
|
81
|
+
config = YAML.load(ERB.new(File.new(config_file).read).result)[environment || Rails.env]
|
82
|
+
raise("Environment #{Rails.env} not defined in config/ruby_skynet.yml") unless config
|
83
|
+
|
84
|
+
@@config = config.dup
|
85
|
+
|
86
|
+
RubySkynet.region = config.delete(:region) || 'Development'
|
87
|
+
RubySkynet.services_path = config.delete(:services_path) || 'app/services'
|
88
|
+
RubySkynet.server_port = config.delete(:server_port) || 2000
|
89
|
+
RubySkynet.local_ip_address = config.delete(:local_ip_address) || Common::local_ip_address
|
106
90
|
|
107
|
-
|
108
|
-
|
109
|
-
RubySkynet.
|
110
|
-
|
111
|
-
|
91
|
+
# Extract just the zookeeper or doozer configuration element
|
92
|
+
key = config[:zookeeper] ? :zookeeper : :doozer
|
93
|
+
RubySkynet.service_registry = ServiceRegistry.new(
|
94
|
+
:root => '/services',
|
95
|
+
key => config.delete(key)
|
96
|
+
)
|
97
|
+
|
98
|
+
config.each_pair {|k,v| RubySkynet::Server.logger.warn "Ignoring unknown RubySkynet config option #{k} => #{v}"}
|
99
|
+
end
|
112
100
|
|
113
|
-
|
101
|
+
# Returns an instance of RubySkynet::Zookeeper::CachedRegistry or RubyDoozer::CachedRegistry
|
102
|
+
# based on which was loaded in RubySkynet.configure!
|
103
|
+
def self.new_cache_registry(root)
|
104
|
+
# Load config
|
105
|
+
service_registry
|
106
|
+
|
107
|
+
if zookeeper = @@config[:zookeeper]
|
108
|
+
RubySkynet::Zookeeper::CachedRegistry.new(:root => root, :zookeeper => zookeeper)
|
109
|
+
else
|
110
|
+
raise "How did we get here", @@config
|
111
|
+
Doozer::CachedRegistry.new(:root => root, :doozer => @@config[:doozer])
|
112
|
+
end
|
114
113
|
end
|
115
114
|
|
116
115
|
end
|
data/lib/ruby_skynet/server.rb
CHANGED
@@ -17,7 +17,7 @@ module RubySkynet
|
|
17
17
|
@@server ||= new(start_port, ip_address)
|
18
18
|
|
19
19
|
# Stop the skynet server on shutdown
|
20
|
-
# To ensure services are de-registered in
|
20
|
+
# To ensure services are de-registered in the service registry
|
21
21
|
at_exit do
|
22
22
|
::RubySkynet::Server.stop
|
23
23
|
end
|
@@ -126,6 +126,18 @@ module RubySkynet
|
|
126
126
|
@listener_thread.join
|
127
127
|
end
|
128
128
|
|
129
|
+
# Registers a Service Class as being available at this server
|
130
|
+
def register_service(klass)
|
131
|
+
logger.info "Registering Service: #{klass.name} with name: #{klass.skynet_name}"
|
132
|
+
::RubySkynet.service_registry.register_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
|
133
|
+
end
|
134
|
+
|
135
|
+
# De-register service from this server
|
136
|
+
def deregister_service(klass)
|
137
|
+
logger.info "De-registering Service: #{klass.name} with name: #{klass.skynet_name}"
|
138
|
+
::RubySkynet.service_registry.deregister_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
|
139
|
+
end
|
140
|
+
|
129
141
|
############################################################################
|
130
142
|
protected
|
131
143
|
|
@@ -204,18 +216,6 @@ module RubySkynet
|
|
204
216
|
logger.debug "Disconnected from the client"
|
205
217
|
end
|
206
218
|
|
207
|
-
# Registers a Service Class as being available at this server
|
208
|
-
def register_service(klass)
|
209
|
-
logger.info "Registering Service: #{klass.name} with name: #{klass.skynet_name}"
|
210
|
-
::RubySkynet.services.register_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
|
211
|
-
end
|
212
|
-
|
213
|
-
# De-register service from this server
|
214
|
-
def deregister_service(klass)
|
215
|
-
logger.info "De-registering Service: #{klass.name} with name: #{klass.skynet_name}"
|
216
|
-
::RubySkynet.services.deregister_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
|
217
|
-
end
|
218
|
-
|
219
219
|
# Called for each message received from the client
|
220
220
|
# Returns a Hash that is sent back to the caller
|
221
221
|
def on_message(skynet_name, method, params)
|
data/lib/ruby_skynet/service.rb
CHANGED
@@ -16,7 +16,7 @@ module RubySkynet
|
|
16
16
|
include SemanticLogger::Loggable
|
17
17
|
end
|
18
18
|
# Register the service with the Server
|
19
|
-
# The server will publish the server to
|
19
|
+
# The server will publish the server to services registry when the server is running
|
20
20
|
Server.register_service(base)
|
21
21
|
end
|
22
22
|
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'semantic_logger'
|
2
2
|
require 'thread_safe'
|
3
3
|
require 'gene_pool'
|
4
4
|
require 'resolv'
|
5
|
-
require 'ruby_doozer'
|
6
5
|
|
7
6
|
#
|
8
7
|
# RubySkynet Sevices Registry
|
@@ -11,71 +10,37 @@ require 'ruby_doozer'
|
|
11
10
|
# all services and which servers they are available on.
|
12
11
|
#
|
13
12
|
module RubySkynet
|
14
|
-
class ServiceRegistry
|
15
|
-
include SyncAttr
|
13
|
+
class ServiceRegistry
|
16
14
|
include SemanticLogger::Loggable
|
17
15
|
|
18
|
-
IPV4_REG_EXP = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
|
19
|
-
|
20
|
-
# Returns [Integer] the score for the supplied ip_address
|
21
|
-
# Score currently ranges from 0 to 4 with 4 being the best score
|
22
|
-
# If the IP address does not match an IP v4 address a DNS lookup will
|
23
|
-
# be performed
|
24
|
-
def self.score_for_server(ip_address, local_ip_address)
|
25
|
-
score = 0
|
26
|
-
# Each matching element adds 1 to the score
|
27
|
-
# 192.168. 0. 0
|
28
|
-
# 1
|
29
|
-
# 1
|
30
|
-
# 1
|
31
|
-
# 1
|
32
|
-
server_match = IPV4_REG_EXP.match(ip_address) || IPV4_REG_EXP.match(Resolv::DNS.new.getaddress(ip_address).to_s)
|
33
|
-
if server_match
|
34
|
-
local_match = IPV4_REG_EXP.match(local_ip_address)
|
35
|
-
score = 0
|
36
|
-
(1..4).each do |i|
|
37
|
-
break if local_match[i].to_i != server_match[i].to_i
|
38
|
-
score += 1
|
39
|
-
end
|
40
|
-
end
|
41
|
-
score
|
42
|
-
end
|
43
|
-
|
44
16
|
# Create a service registry
|
45
17
|
# See: RubyDoozer::Registry for the parameters
|
46
18
|
def initialize(params)
|
47
|
-
super
|
48
|
-
|
49
19
|
# Registry has the following format
|
50
20
|
# Key: [String] 'name/version/region'
|
51
21
|
# Value: [Array<String>] 'host:port', 'host:port'
|
52
|
-
@
|
53
|
-
|
54
|
-
path = "#{@root_path}/**"
|
55
|
-
doozer_pool.with_connection do |doozer|
|
56
|
-
@current_revision = doozer.current_revision
|
57
|
-
# Fetch all the configuration information from Doozer and set the internal copy
|
58
|
-
doozer.walk(path, @current_revision) do |path, value|
|
59
|
-
service_info_changed(relative_key(path), value)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Start monitoring thread
|
64
|
-
monitor_thread
|
22
|
+
@cache = ThreadSafe::Hash.new
|
65
23
|
|
24
|
+
# Supply block to load the current keys from the Registry
|
25
|
+
@registry = Registry.new(params) do |key, value|
|
26
|
+
service_info_changed(key, value)
|
27
|
+
end
|
66
28
|
# Register Callbacks
|
67
|
-
on_update {|path, value| service_info_changed(path, value) }
|
68
|
-
on_delete {|path
|
29
|
+
@registry.on_update {|path, value| service_info_changed(path, value) }
|
30
|
+
@registry.on_delete {|path| service_info_changed(path) }
|
31
|
+
|
32
|
+
# Zookeeper Registry also supports on_create
|
33
|
+
@registry.on_create {|path, value| service_info_changed(path, value) } if @registry.respond_to?(:on_create)
|
69
34
|
end
|
70
35
|
|
71
36
|
# Returns the Service Registry as a Hash
|
72
37
|
def to_h
|
73
|
-
@
|
38
|
+
@cache.dup
|
74
39
|
end
|
75
40
|
|
76
41
|
# Register the supplied service at this Skynet Server host and Port
|
77
42
|
def register_service(name, version, region, hostname, port)
|
78
|
-
|
43
|
+
@registry["#{name}/#{version}/#{region}/#{hostname}/#{port}"] = {
|
79
44
|
"Config" => {
|
80
45
|
"UUID" => "#{hostname}:#{port}-#{$$}-#{name}-#{version}",
|
81
46
|
"Name" => name,
|
@@ -93,7 +58,7 @@ module RubySkynet
|
|
93
58
|
|
94
59
|
# Deregister the supplied service from the Registry
|
95
60
|
def deregister_service(name, version, region, hostname, port)
|
96
|
-
delete("#{name}/#{version}/#{region}/#{hostname}/#{port}")
|
61
|
+
@registry.delete("#{name}/#{version}/#{region}/#{hostname}/#{port}")
|
97
62
|
end
|
98
63
|
|
99
64
|
# Return a server that implements the specified service
|
@@ -113,14 +78,14 @@ module RubySkynet
|
|
113
78
|
if version == '*'
|
114
79
|
# Find the highest version for the named service in this region
|
115
80
|
version = -1
|
116
|
-
@
|
81
|
+
@cache.keys.each do |key|
|
117
82
|
if match = key.match(/#{name}\/(\d+)\/#{region}/)
|
118
83
|
ver = match[1].to_i
|
119
84
|
version = ver if ver > version
|
120
85
|
end
|
121
86
|
end
|
122
87
|
end
|
123
|
-
if server_infos = @
|
88
|
+
if server_infos = @cache["#{name}/#{version}/#{region}"]
|
124
89
|
server_infos.first.servers
|
125
90
|
end
|
126
91
|
end
|
@@ -138,6 +103,7 @@ module RubySkynet
|
|
138
103
|
|
139
104
|
# Service information changed in doozer, so update internal registry
|
140
105
|
def service_info_changed(path, value=nil)
|
106
|
+
logger.info("service_info_changed: #{path}", value)
|
141
107
|
# path: "TutorialService/1/Development/127.0.0.1/9000"
|
142
108
|
e = path.split('/')
|
143
109
|
|
@@ -171,7 +137,7 @@ module RubySkynet
|
|
171
137
|
def add_server(key, hostname, port)
|
172
138
|
server = "#{hostname}:#{port}"
|
173
139
|
|
174
|
-
server_infos = (@
|
140
|
+
server_infos = (@cache[key] ||= ThreadSafe::Array.new)
|
175
141
|
|
176
142
|
# If already present, then nothing to do
|
177
143
|
server_info = server_infos.find{|si| si.servers.include?(server)}
|
@@ -205,7 +171,7 @@ module RubySkynet
|
|
205
171
|
server = "#{hostname}:#{port}"
|
206
172
|
logger.info "Service: #{key} stopped running at #{server}"
|
207
173
|
server_info = nil
|
208
|
-
if server_infos = @
|
174
|
+
if server_infos = @cache[key]
|
209
175
|
server_infos.each do |si|
|
210
176
|
if si.servers.delete(server)
|
211
177
|
server_info = si
|
@@ -219,7 +185,7 @@ module RubySkynet
|
|
219
185
|
server_infos.delete(server_info) if server_info.servers.size == 0
|
220
186
|
|
221
187
|
# Cleanup if no more server infos
|
222
|
-
@
|
188
|
+
@cache.delete(key) if server_infos.size == 0
|
223
189
|
|
224
190
|
server_removed(server) if notify
|
225
191
|
end
|
@@ -241,5 +207,32 @@ module RubySkynet
|
|
241
207
|
end
|
242
208
|
end
|
243
209
|
|
210
|
+
IPV4_REG_EXP = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
|
211
|
+
|
212
|
+
# Returns [Integer] the score for the supplied ip_address
|
213
|
+
# Score currently ranges from 0 to 4 with 4 being the best score
|
214
|
+
# If the IP address does not match an IP v4 address a DNS lookup will
|
215
|
+
# be performed
|
216
|
+
def self.score_for_server(ip_address, local_ip_address)
|
217
|
+
ip_address = '127.0.0.1' if ip_address == 'localhost'
|
218
|
+
score = 0
|
219
|
+
# Each matching element adds 1 to the score
|
220
|
+
# 192.168. 0. 0
|
221
|
+
# 1
|
222
|
+
# 1
|
223
|
+
# 1
|
224
|
+
# 1
|
225
|
+
server_match = IPV4_REG_EXP.match(ip_address) || IPV4_REG_EXP.match(Resolv::DNS.new.getaddress(ip_address).to_s)
|
226
|
+
if server_match
|
227
|
+
local_match = IPV4_REG_EXP.match(local_ip_address)
|
228
|
+
score = 0
|
229
|
+
(1..4).each do |i|
|
230
|
+
break if local_match[i].to_i != server_match[i].to_i
|
231
|
+
score += 1
|
232
|
+
end
|
233
|
+
end
|
234
|
+
score
|
235
|
+
end
|
236
|
+
|
244
237
|
end
|
245
238
|
end
|
data/lib/ruby_skynet/version.rb
CHANGED