jerbil 1.2.2
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.
- data/Bugs.rdoc +66 -0
- data/Gemfile +12 -0
- data/History.txt +359 -0
- data/Intro.txt +5 -0
- data/LICENCE.rdoc +159 -0
- data/README.md +335 -0
- data/README_SERVICES.md +410 -0
- data/README_TESTING.md +47 -0
- data/bin/jerbil +62 -0
- data/bin/jerbil-install +56 -0
- data/etc/conf.d/jerbild +15 -0
- data/etc/conf.d/jserviced +39 -0
- data/etc/init.d/jerbild +55 -0
- data/etc/init.d/jserviced +59 -0
- data/etc/jerbil/jerbil-client.rb +2 -0
- data/etc/jerbil/jerbil.rb +83 -0
- data/lib/jerbil.rb +636 -0
- data/lib/jerbil/config.md +49 -0
- data/lib/jerbil/config.rb +67 -0
- data/lib/jerbil/errors.rb +74 -0
- data/lib/jerbil/jerbil_service/base.rb +191 -0
- data/lib/jerbil/jerbil_service/client.rb +325 -0
- data/lib/jerbil/jerbil_service/config.md +119 -0
- data/lib/jerbil/jerbil_service/config.rb +72 -0
- data/lib/jerbil/jerbil_service/sclient.rb +343 -0
- data/lib/jerbil/jerbil_service/support.rb +58 -0
- data/lib/jerbil/jerbil_service/utils.rb +35 -0
- data/lib/jerbil/servers.rb +230 -0
- data/lib/jerbil/service.rb +216 -0
- data/lib/jerbil/support.rb +160 -0
- data/lib/jerbil/thor/server.rb +76 -0
- data/lib/jerbil/thor/service.rb +74 -0
- data/lib/jerbil/version.rb +13 -0
- data/sbin/jerbil-status +120 -0
- data/sbin/jerbil-stop +139 -0
- data/sbin/jerbild +186 -0
- data/sbin/jservice-status +107 -0
- data/sbin/jservice-stop +94 -0
- data/sbin/jserviced +111 -0
- data/spec/jerbil_2_jerbil_spec.rb +87 -0
- data/spec/jerbil_client1_spec.rb +80 -0
- data/spec/jerbil_client_spec.rb +114 -0
- data/spec/jerbil_client_stop_spec.rb +24 -0
- data/spec/jerbil_daemonised/jerbil_local_spec.rb +81 -0
- data/spec/jerbil_daemonised/jerbil_remote_spec.rb +116 -0
- data/spec/jerbil_load.rb +48 -0
- data/spec/jerbil_local_spec.rb +91 -0
- data/spec/jerbil_missing_spec.rb +98 -0
- data/spec/jerbil_remote_spec.rb +117 -0
- data/spec/jerbil_remote_spec_bup.rb +168 -0
- data/spec/jerbil_service_error_spec.rb +56 -0
- data/spec/jerbil_service_spec.rb +41 -0
- data/spec/jerbil_support_spec.rb +69 -0
- data/spec/jservice_utils_spec.rb +38 -0
- data/spec/server_spec.rb +69 -0
- data/spec/server_update_spec.rb +28 -0
- data/spec/service_spec.rb +72 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/test_env_spec.rb +53 -0
- data/test/bad_test_service.rb +31 -0
- data/test/conf.d/jerbil +36 -0
- data/test/conf.d/jerbil.conf +39 -0
- data/test/conf.d/jerbil.rb +55 -0
- data/test/conf.d/jerbil_local.rb +33 -0
- data/test/conf.d/jerbil_no_local.conf +39 -0
- data/test/conf.d/jerbil_old.rb +47 -0
- data/test/conf.d/jerbil_test.rb +35 -0
- data/test/conf.d/malformed +1 -0
- data/test/conf.d/missing_services +39 -0
- data/test/conf.d/ruby_test.rb +8 -0
- data/test/init.d/jerbild +14 -0
- data/test/jerbil.rb +51 -0
- data/test/jerbil_config.rb +8 -0
- data/test/jstop.rb +36 -0
- data/test/key.asc +1 -0
- data/test/lib/ruby_test.rb +37 -0
- data/test/lib/ruby_test/config.rb +56 -0
- data/test/lib/ruby_test/version.rb +13 -0
- data/test/pids/jerbil-prod.asc +1 -0
- data/test/pids/jerbil-prod.pid +1 -0
- data/test/pids/jerbil.pid +1 -0
- data/test/private_key_file.asc +3 -0
- data/test/service-stop.rb +86 -0
- data/test/service_mock.rb +94 -0
- data/test/test_service_client.rb +25 -0
- metadata +265 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# Description
|
3
|
+
#
|
4
|
+
# Author:: Robert Sharp
|
5
|
+
# Copyright:: Copyright (c) 2010 Robert Sharp
|
6
|
+
# License:: Open Software Licence v3.0
|
7
|
+
#
|
8
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
9
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
10
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
11
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
12
|
+
#
|
13
|
+
#
|
14
|
+
|
15
|
+
|
16
|
+
module JerbilService
|
17
|
+
|
18
|
+
# Support methods that should be used to extend a service module
|
19
|
+
#
|
20
|
+
# module RubyTest
|
21
|
+
# extend JerbilService::Support
|
22
|
+
#
|
23
|
+
# class Service ...
|
24
|
+
#
|
25
|
+
#
|
26
|
+
module Support
|
27
|
+
|
28
|
+
# get the config settings for the given service module.
|
29
|
+
#
|
30
|
+
# This uses Jeckyl configuration and defaults to the conf file for the service module
|
31
|
+
# in the location defined by Jeckyl::ConfigRoot.
|
32
|
+
#
|
33
|
+
# e.g. for RubyTest, it will default to /etc/jermine/rubytest.rb
|
34
|
+
#
|
35
|
+
# Provide a different filename to change this.
|
36
|
+
#
|
37
|
+
def get_config(config_file=nil)
|
38
|
+
# check that the config_file has been specified
|
39
|
+
if config_file.nil? then
|
40
|
+
# no, so set the default
|
41
|
+
config_file = Jeckyl::ConfigRoot + "/#{self.to_s.downcase}.rb"
|
42
|
+
end
|
43
|
+
|
44
|
+
# read the config file
|
45
|
+
return self::Config.new(config_file)
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
# get the identity of this module, assuming this has been
|
50
|
+
# set up and is maintained by Jevoom
|
51
|
+
# Returns 'n/a' otherwise
|
52
|
+
def ident
|
53
|
+
return self::Ident
|
54
|
+
rescue
|
55
|
+
return 'n/a'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# = Jerbil SService Utilities
|
4
|
+
#
|
5
|
+
# == Methods to assist setting up a Jerbil Service
|
6
|
+
#
|
7
|
+
# Author:: Robert Sharp
|
8
|
+
# Copyright:: Copyright (c) 2012 Robert Sharp
|
9
|
+
# License:: Open Software Licence v3.0
|
10
|
+
#
|
11
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
12
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
13
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
14
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
|
19
|
+
module JerbilService
|
20
|
+
|
21
|
+
# misc. methods for Jerbil scripts
|
22
|
+
module Utils
|
23
|
+
|
24
|
+
# convert a filename etc to a proper class name
|
25
|
+
# For example, converts 'my_service' to 'MyService'
|
26
|
+
#
|
27
|
+
# @param [String] string to convert to a classname
|
28
|
+
# @return [String] converted classname
|
29
|
+
def Utils.classify(string)
|
30
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
31
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
#
|
2
|
+
# = Jerbil Server Class
|
3
|
+
#
|
4
|
+
# Author:: Robert Sharp
|
5
|
+
# Copyright:: Copyright (c) 2010 Robert Sharp
|
6
|
+
# License:: Open Software Licence v3.0
|
7
|
+
#
|
8
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
9
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
10
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
11
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# A useful class for managing information about Jerbil Servers
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
require 'socket'
|
19
|
+
require 'timeout'
|
20
|
+
require 'netaddr'
|
21
|
+
require 'resolv'
|
22
|
+
require 'drb'
|
23
|
+
|
24
|
+
module Jerbil
|
25
|
+
|
26
|
+
# An informational class for servers on the network, used by brokers to keep track of each other
|
27
|
+
# and by services and clients to find the local broker
|
28
|
+
class Servers
|
29
|
+
|
30
|
+
# return a record for the local server
|
31
|
+
#
|
32
|
+
# @param [Symbol] env being one of :dev, :test, :prod, and defaulting to :prod
|
33
|
+
# @param [Boolean] check set true to ensure server is running
|
34
|
+
# @raise [Jerbil::MissingServer] if server is not running
|
35
|
+
#
|
36
|
+
def self.get_local_server(env=nil, check=false)
|
37
|
+
env ||= :prod
|
38
|
+
hostname = Socket.gethostname
|
39
|
+
ip = Resolv.getaddress(hostname)
|
40
|
+
port = self.get_port(env)
|
41
|
+
return self.new(hostname, '', env, port) if ! check || self.server_up?(ip, port, 0.1)
|
42
|
+
raise Jerbil::MissingServer, "Cannot find local server on #{hostname}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# create the local server record
|
46
|
+
#
|
47
|
+
# used by {Jerbil::Broker} during startup to create its own record
|
48
|
+
#
|
49
|
+
# @param [Symbol] env being one of :dev, :test, :prod
|
50
|
+
# @param [String] pkey the private key for this server
|
51
|
+
# @return [Jerbil::Servers] a server record
|
52
|
+
def self.create_local_server(env, pkey)
|
53
|
+
hostname = Socket.gethostname
|
54
|
+
port = self.get_port(env)
|
55
|
+
return self.new(hostname, pkey, env, port)
|
56
|
+
end
|
57
|
+
|
58
|
+
# return the server with the given fqdn
|
59
|
+
# @deprecated NOT USED ANYWHERE?
|
60
|
+
def self.get_server(servers, fqdn, env=:prod)
|
61
|
+
servers.each {|server| return server if server.fqdn == fqdn && server.env == env}
|
62
|
+
# found nothing to match
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
|
66
|
+
# scan the lan for open ports and return an array of servers
|
67
|
+
# for each.
|
68
|
+
#
|
69
|
+
# These server records have blank keys. {Jerbil::Broker#register_server} will return
|
70
|
+
# the called servers key, which can then be set with {Jerbil::Servers#set_key}.
|
71
|
+
#
|
72
|
+
# The netaddress and netmask are defined in {Jerbil::Config} where further details
|
73
|
+
# about these parameters can be found.
|
74
|
+
#
|
75
|
+
# @param [Symbol] env being the environment in which the servers should be running
|
76
|
+
# @param [String] netaddress for the network to search
|
77
|
+
# @param [Numeric] netmask to limit the search
|
78
|
+
# @param [Float] seconds to wait before timing out
|
79
|
+
# @return [Array] of {jerbil::Servers} that were found
|
80
|
+
def self.find_servers(env, netaddress, netmask, seconds=0.1)
|
81
|
+
# get the port number for jerbil
|
82
|
+
port = self.get_port(env)
|
83
|
+
naddr = NetAddr::CIDR.create("#{netaddress}/#{netmask.to_s}")
|
84
|
+
servers = []
|
85
|
+
|
86
|
+
naddr.enumerate.each do |ip|
|
87
|
+
servers << self.new(Resolv.getname(ip), '', env, port) if self.server_up?(ip, port, seconds)
|
88
|
+
end
|
89
|
+
# servers.each do |server|
|
90
|
+
# server.get_key
|
91
|
+
# end
|
92
|
+
return servers
|
93
|
+
end
|
94
|
+
|
95
|
+
# create a new server record with
|
96
|
+
#
|
97
|
+
# @param [String] fqdn - string fully qualified domain name
|
98
|
+
# @param [String] key - private access key for system methods
|
99
|
+
# @param [Symbol] env to set the environment to :dev, :test or :prod
|
100
|
+
# @param [Numeric] port - optional integer for port number
|
101
|
+
#
|
102
|
+
def initialize(fqdn, key, env=:prod, port=nil)
|
103
|
+
@fqdn = fqdn
|
104
|
+
@key = key
|
105
|
+
@env = env
|
106
|
+
if port.nil? then
|
107
|
+
@port = Socket.getservbyname('jerbil')
|
108
|
+
@port += 1 if env == :test
|
109
|
+
@port += 2 if env == :dev
|
110
|
+
else
|
111
|
+
@port = port
|
112
|
+
end
|
113
|
+
@active = false
|
114
|
+
end
|
115
|
+
|
116
|
+
# the full-qualified domain name for the server
|
117
|
+
attr_reader :fqdn
|
118
|
+
|
119
|
+
# the private key for the server
|
120
|
+
attr_reader :key
|
121
|
+
|
122
|
+
# the port for the server
|
123
|
+
attr_reader :port
|
124
|
+
|
125
|
+
# the environment that the server is running in
|
126
|
+
attr_reader :env
|
127
|
+
|
128
|
+
# test for equality
|
129
|
+
#
|
130
|
+
# ensure equality is across name, key and port.
|
131
|
+
# no need to test env because port is unique enough
|
132
|
+
#
|
133
|
+
# @param [Jerbil::Servers] rhs server to compare
|
134
|
+
def ==(rhs)
|
135
|
+
@fqdn == rhs.fqdn && @key == rhs.key && @port == rhs.port
|
136
|
+
end
|
137
|
+
|
138
|
+
# convenience method to assist Jerbil internals with DRb
|
139
|
+
#
|
140
|
+
# drb_address makes it easier to start a DRb server, which
|
141
|
+
# is done outside this class because it should only be done
|
142
|
+
# under specific circumstances, and not by the general users of this class
|
143
|
+
#
|
144
|
+
# @return [String] the servers DRb address
|
145
|
+
def drb_address
|
146
|
+
"druby://#{@fqdn}:#{@port}"
|
147
|
+
end
|
148
|
+
|
149
|
+
# connect to this server.
|
150
|
+
#
|
151
|
+
# Always assumes that the caller has a DRb service
|
152
|
+
# running. Jerbil certainly should!
|
153
|
+
#
|
154
|
+
# @raise [ServerConnectError] if anything goes wrong
|
155
|
+
def connect
|
156
|
+
DRbObject.new(nil, self.drb_address)
|
157
|
+
rescue Exception
|
158
|
+
raise ServerConnectError
|
159
|
+
end
|
160
|
+
|
161
|
+
# get the key for this server from the actual server
|
162
|
+
# @return [String] private key
|
163
|
+
def get_key
|
164
|
+
@key = self.connect.get_key
|
165
|
+
end
|
166
|
+
|
167
|
+
# save the key for this server, ensuring it is local
|
168
|
+
#
|
169
|
+
# @param [String] pkey - the server's private key'
|
170
|
+
def set_key(pkey)
|
171
|
+
@key = pkey
|
172
|
+
end
|
173
|
+
|
174
|
+
# return a string name for the server
|
175
|
+
#
|
176
|
+
# @return [String] ident string
|
177
|
+
def ident
|
178
|
+
"#{@fqdn}[:#{@env}]"
|
179
|
+
end
|
180
|
+
|
181
|
+
# create a deep copy of the server object.
|
182
|
+
#
|
183
|
+
# @return [Jerbil::Server] copy of self
|
184
|
+
def copy
|
185
|
+
return ServerRecord.new(self.fqdn, self.key, self.env, self.port)
|
186
|
+
end
|
187
|
+
|
188
|
+
# check if the given server is running
|
189
|
+
#
|
190
|
+
# This is intended for internal use only by {Jerbil::Servers.find_servers}.
|
191
|
+
#
|
192
|
+
# @param [String] ip address of server to test
|
193
|
+
# @param [Integer] port for server
|
194
|
+
# @param [Float] timeout_secs to wait for a response
|
195
|
+
# @return [Boolean] true if server is up
|
196
|
+
def self.server_up?(ip, port, timeout_secs)
|
197
|
+
#puts "Checking for #{ip}:#{port}"
|
198
|
+
Timeout::timeout(timeout_secs) do
|
199
|
+
begin
|
200
|
+
TCPSocket.new(ip, port).close
|
201
|
+
true
|
202
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
203
|
+
false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
rescue Timeout::Error
|
207
|
+
false
|
208
|
+
end
|
209
|
+
|
210
|
+
# get the port for the Jerbil Server
|
211
|
+
#
|
212
|
+
# Note that jerbil and all its services expect
|
213
|
+
# three consecutive ports to be available, one for each environment.
|
214
|
+
# The first port should be :prod, then :test and finally :dev
|
215
|
+
#
|
216
|
+
# @param [Symbol] env the environment in which the servers are running
|
217
|
+
# @raise [Jerbil::MissingJerbilService] if jerbil is not in /etc/services
|
218
|
+
#
|
219
|
+
def self.get_port(env)
|
220
|
+
port = Socket.getservbyname('jerbil')
|
221
|
+
port += 1 if env == :test
|
222
|
+
port += 2 if env == :dev
|
223
|
+
return port
|
224
|
+
rescue SocketError
|
225
|
+
raise Jerbil::MissingJerbilService, "There is no service 'jerbil' in /etc/services"
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
#
|
2
|
+
# Jerbil Service Object
|
3
|
+
#
|
4
|
+
# Author:: Robert Sharp
|
5
|
+
# Copyright:: Copyright (c) 2010 Robert Sharp
|
6
|
+
# License:: Open Software Licence v3.0
|
7
|
+
#
|
8
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
9
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
10
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
11
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# Service contains information about a service registered with Jerbil
|
15
|
+
#
|
16
|
+
require 'jerbil/errors'
|
17
|
+
require 'socket'
|
18
|
+
require 'digest/sha1'
|
19
|
+
|
20
|
+
module Jerbil
|
21
|
+
|
22
|
+
# Define a service record for a service to register with Jerbil
|
23
|
+
#
|
24
|
+
# Used internally by {Jerbil::Broker} and {JerbilService} to record information about
|
25
|
+
# running services. Is made available to users through the {JerbilService::Client}
|
26
|
+
# interface where it can be used, for example, to get the service's key.
|
27
|
+
#
|
28
|
+
class ServiceRecord
|
29
|
+
|
30
|
+
# create a new service record object
|
31
|
+
#
|
32
|
+
# Note that the callback parameters do not really need to be considered
|
33
|
+
# if you are using {JerbilService::Base}
|
34
|
+
#
|
35
|
+
# @param [Symbol] name identifying the service - needs to match /etc/services
|
36
|
+
# or create fails with the exception InvalidService
|
37
|
+
# @param [Symbol] env identify the service's environment. Allows multiple
|
38
|
+
# services to operate for development etc
|
39
|
+
# @param [Symbol] verify_callback being the name of the method to call to check
|
40
|
+
# that the service is working
|
41
|
+
# @param [Symbol] stop_callback as above but the method stops the service
|
42
|
+
# @return [ServiceRecord] of course
|
43
|
+
# @raise [InvalidService] if the service is not registered through /etc/services
|
44
|
+
def initialize(name, env, verify_callback=:verify_callback, stop_callback=nil)
|
45
|
+
@host = Socket.gethostname
|
46
|
+
@name = name
|
47
|
+
begin
|
48
|
+
@port = Socket.getservbyname(@name.to_s)
|
49
|
+
rescue
|
50
|
+
raise InvalidService, "No service registered as: #{name}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# now increment it if not production
|
54
|
+
@port += 1 if env == :test
|
55
|
+
@port += 2 if env == :dev
|
56
|
+
|
57
|
+
@env = env
|
58
|
+
@key = Digest::SHA1.hexdigest(Time.now.to_s + rand(12341234).to_s)[1..10]
|
59
|
+
@pid = Process.pid
|
60
|
+
@verify_callback = verify_callback
|
61
|
+
@stop_callback = stop_callback
|
62
|
+
@lock = nil
|
63
|
+
@address = @host + ':' + @port.to_s
|
64
|
+
@registered_at = nil
|
65
|
+
@access_count = 0
|
66
|
+
@accessed_at = nil
|
67
|
+
@close = true
|
68
|
+
end
|
69
|
+
|
70
|
+
# name of the service
|
71
|
+
attr_reader :name
|
72
|
+
# environment the service is running in
|
73
|
+
attr_reader :env
|
74
|
+
# the key needed to access the service
|
75
|
+
attr_reader :key
|
76
|
+
# the host on which the service is running
|
77
|
+
attr_reader :host
|
78
|
+
# the full DRb address used to contact the service
|
79
|
+
# This is only required by Jerbil and should not be needed
|
80
|
+
# by the casual user.
|
81
|
+
attr_reader :address
|
82
|
+
# the port used by the service
|
83
|
+
attr_reader :port
|
84
|
+
# the date/time at which the service was registered with Jerbil
|
85
|
+
attr_reader :registered_at
|
86
|
+
# the number of times the service has been accessed on Jerbil
|
87
|
+
# since it was registered
|
88
|
+
attr_reader :access_count
|
89
|
+
# the date/time at which the service was last accessed
|
90
|
+
attr_reader :accessed_at
|
91
|
+
|
92
|
+
# method to allow Jerbil to set when the service was registered
|
93
|
+
def register
|
94
|
+
@registered_at = Time.now
|
95
|
+
@accessed_at = @registered_at
|
96
|
+
end
|
97
|
+
|
98
|
+
# method to allow Jerbil to record an access to this service
|
99
|
+
def log_access
|
100
|
+
@accessed_at = Time.now
|
101
|
+
@access_count += 1
|
102
|
+
end
|
103
|
+
|
104
|
+
# return a string containing the name, env, host etc
|
105
|
+
def ident
|
106
|
+
"#{@name}[#{@env}]@#{@address}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# return a hash containing the find arguments for self
|
110
|
+
def args
|
111
|
+
{:name=>@name, :env=>@env, :host=>@host, :key=>@key}
|
112
|
+
end
|
113
|
+
|
114
|
+
# compare services according to a set of arguments
|
115
|
+
#
|
116
|
+
# This will return true if the service matches the given keys. An argument of nil
|
117
|
+
# matches all services. Uses the same arguments as {Jerbil::Broker#find} except
|
118
|
+
# that it will ignore the :ignore_access argument!
|
119
|
+
#
|
120
|
+
# @param (see Jerbil::Broker#find)
|
121
|
+
# @option (see Jerbil::Broker#find)
|
122
|
+
#
|
123
|
+
def matches?(args={})
|
124
|
+
options = {:name => nil, :env => nil, :host=>nil, :key => nil}.merge(args)
|
125
|
+
is_equal = true
|
126
|
+
is_equal = @name == options[:name] unless options[:name].nil?
|
127
|
+
is_equal = is_equal && @env == options[:env] unless options[:env].nil?
|
128
|
+
is_equal = is_equal && @host == options[:host] unless options[:host].nil?
|
129
|
+
is_equal = is_equal && @key == options[:key] unless options[:key].nil?
|
130
|
+
return is_equal
|
131
|
+
end
|
132
|
+
|
133
|
+
# compares services directly and returns true if they have the same
|
134
|
+
# name, env, and host.
|
135
|
+
#
|
136
|
+
# Note that this ignores the service records key, allowing you to find
|
137
|
+
# instances of the same service e.g. that have previously been registered.
|
138
|
+
#
|
139
|
+
# @param [ServiceRecord] rhs service to compare to this one
|
140
|
+
def same_service?(rhs)
|
141
|
+
self.matches?(:name=>rhs.name, :env=>rhs.env, :host=>rhs.host)
|
142
|
+
end
|
143
|
+
|
144
|
+
# compares services directly and returns true if they have the same
|
145
|
+
# name, env, host and key
|
146
|
+
#
|
147
|
+
# @param (see Jerbil::ServiceRecord#same_service?)
|
148
|
+
def ==(rhs)
|
149
|
+
self.matches?(:name=>rhs.name, :env=>rhs.env, :host=>rhs.host, :key=>rhs.key)
|
150
|
+
end
|
151
|
+
|
152
|
+
# connect to the service represented by this record
|
153
|
+
#
|
154
|
+
# You do not need to use this method if you use {JerbilService::Client} to
|
155
|
+
# manage the client-server interface direct.
|
156
|
+
#
|
157
|
+
# This return a DRb session for the given service
|
158
|
+
# set verify to true (default) to call the
|
159
|
+
# services keep_alive method
|
160
|
+
#
|
161
|
+
# @param [Boolean] verify if the service is running immedaitely after connecting
|
162
|
+
# @raise [ServiceCallbackMissing] if the verify method in this record does not
|
163
|
+
# match the methods of the service being connected to (you have mucked it up!)
|
164
|
+
# @raise [ServiceConnectError] if any other exception is raised during the connect
|
165
|
+
# process.
|
166
|
+
def connect(verify=true)
|
167
|
+
self.start_drb_if_needed
|
168
|
+
service = DRbObject.new(nil, "druby://#{@address}")
|
169
|
+
key = service.send(@verify_callback, @key) if verify
|
170
|
+
return service
|
171
|
+
rescue NoMethodError
|
172
|
+
raise ServiceCallbackMissing
|
173
|
+
rescue
|
174
|
+
raise ServiceConnectError
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
# convenience method to assist JerbilService actions
|
179
|
+
#
|
180
|
+
# drb_address makes it easier to start a DRb server, which
|
181
|
+
# is done outside this class because it should only be done
|
182
|
+
# under specific circumstances, and not by the general users of this class
|
183
|
+
#
|
184
|
+
def drb_address
|
185
|
+
"druby://#{@host}:#{@port}"
|
186
|
+
end
|
187
|
+
|
188
|
+
# is the service local to the caller?
|
189
|
+
def local?
|
190
|
+
return @host == Socket.gethostname
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
# close the connection to the service
|
195
|
+
def close
|
196
|
+
DRb.stop_service if @close
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
protected
|
201
|
+
|
202
|
+
# ensures that there is a DRb session running before trying to use
|
203
|
+
# DRb services
|
204
|
+
def start_drb_if_needed
|
205
|
+
DRb.current_server
|
206
|
+
@close = false
|
207
|
+
rescue
|
208
|
+
DRb.start_service
|
209
|
+
@close = true
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
end
|