Class: JerbilService::Client
- Inherits:
-
Object
- Object
- JerbilService::Client
- Defined in:
- lib/jerbil/jerbil_service/client.rb
Overview
JerbilService::Client provides a wrapper around a Base type service that hides all interaction with Jerbil itself, enabling client interfaces with a service to be constructed quickly and painlessly
To use, call the Client.find_services method, which yields a block for each matching service registered with the Jerbil Server. The service’s methods can then be called on the yielded object, which are then transparently passed back to the service itself.
It should always be remembered that these method calls will be mediated through Ruby’s DRb mechanisms and therefore access to objects across this interface may not be the same as accessing them directly. See Services Readme for more details
Class Method Summary collapse
-
.connect(modl, options = {}, &block) ⇒ Object
deprecated
Deprecated.
Use Client.find_services instead
-
.find_services(what, modl, options = {}) {|service| ... } ⇒ Object
Connect to a one or more instances of a service using Jerbil.
-
.get_config(modl, config_file = nil) ⇒ Object
return the server’s config options for the given file, or the default if none given.
Instance Method Summary collapse
- #connect(index = :all, &block) ⇒ Object
-
#host ⇒ String
return the name of the host on which the service is running.
-
#initialize(modl, options, &block) ⇒ Client
constructor
A new instance of Client.
- #method_missing(symb, *parameters) ⇒ Object
-
#service_key ⇒ String
return the service key for the given service, which can be used by the caller where a method requires.
-
#verify ⇒ Boolean
verify that the service is working.
Constructor Details
#initialize(modl, options, &block) ⇒ Client
Returns a new instance of Client.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/jerbil/jerbil_service/client.rb', line 152 def initialize(modl, , &block) @klass = modl::Service name = modl.to_s name_symbol = name.downcase.to_sym quiet = [:quiet] unless quiet @output = [:output] || $stderr else @output = File.open('/dev/null', 'w') end @welcome = [:welcome] @output.puts "Welcome to #{name} (#{modl.ident})" if @welcome unless quiet @output.puts "Options:" .each {|key, val| @output.puts(" #{key}:#{val}") } end env = [:environment] service_opts = {:name=>name_symbol, :env=>env} service_opts[:host] = Socket.gethostname if [:local] begin # find jerbil @jerbil_server = Jerbil::Servers.get_local_server([:jerbil_env]) # now connect to it jerbil = @jerbil_server.connect # and find all of the services @services = [] @services = jerbil.find(service_opts) if @services.length == 0 then @output.puts "No services for #{name}[:#{env}] were found" raise Jerbil::ServiceNotFound, "No services for #{name}[:#{env}] were found" end block.call(self) @output.puts "Stopping the service" if @welcome #output.close unless @output == $stderr return nil # give the caller nothing back rescue Jerbil::MissingServer @output.puts("Cannot find a local Jerbil server") raise rescue Jerbil::JerbilConfigError => err @output.puts("Error in Jerbil Config File: #{err.}") raise rescue Jerbil::JerbilServiceError =>jerr @output.puts("Error with Jerbil Service: #{jerr.}") raise rescue Jerbil::ServerConnectError @output.puts("Error connecting to Jerbil Server") raise rescue DRb::DRbConnError =>derr @output.puts("Error setting up DRb Server: #{derr.}") raise Jerbil::ServerConnectError end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symb, *parameters) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/jerbil/jerbil_service/client.rb', line 274 def method_missing(symb, *parameters) # stop anyone from calling the stop method raise Jerbil::UnauthorizedMethod if symb == :stop_callback # make sure this is a valid method of the receiving instance # This is needed cos sending an unknown method over DRb with $SAFE = 1 # raises a Security Error. Could catch this, but it might happen for # different reasons so best not to. # need to fix symbols problem if String.instance_methods.first.instance_of?(String) then # < 1.9 Ruby method_id = symb.to_s #@output.puts "Setting method id to a string: #{method_id}" else method_id = symb #@output.puts "Ensuring method id is a symbol: #{method_id}" end unless @klass.instance_methods.include?(method_id) @output.puts "Failed to find method id:" @output.puts "#{@klass.instance_methods.inspect}" raise NoMethodError, "Failed to find method: #{method_id}" end retries = 0 begin @session.send(symb, *parameters) rescue DRb::DRbConnError # service did not respond nicely @output.puts "Failed to connected to the service - checking its OK" jerbil = @jerbil_server.connect if jerbil.service_missing?(@service) then # something nasty has occurred @output.puts "Jerbil confirms the service is missing" raise Jerbil::ServiceConnectError, "Service is missing" else # seems jerbil thinks its ok, so try again retries += 1 @output.puts "Jerbil thinks the service is OK, retrying" retry unless retries > 2 @output.puts "Retried too many times, giving up" raise Jerbil::ServiceConnectError, "Service is not responding" end end end |
Class Method Details
.connect(modl, options = {}, &block) ⇒ Object
Use find_services instead
backwards compatible method to connect to first service using environment defined in config_file which is read in from options or the default location (see get_config)
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/jerbil/jerbil_service/client.rb', line 138 def self.connect(modl, ={}, &block) # :yields: client config_file = [:config_file] config = modl.get_config(config_file) [:environment] ||= config[:environment] [:jerbil_env] ||= config[:jerbil_env] self.find_services(:first, modl, , &block) end |
.find_services(what, modl, options = {}) {|service| ... } ⇒ Object
Connect to a one or more instances of a service using Jerbil
The method will search the Jerbil Server for services of the given module, as defined by the what parameter:
-
:first, yields the block once with the first service regardless of how many services there are
and with no guarantee about which services this might be
-
:local, yields the service running on the same processor as the client
-
:all, yields the block for each service.
Within the block, the user can call any of the service’s methods, together with the instance methods of the client itself.
For example, to find a service running on a particular host:
JerbilService::Client.find_services(:all, MyService, opts) do |service|
if service.host == 'a_server.network.com' then
# found the services I am looking for, now do something
...
end
end
To find a service running in a particular environment, you need to set the above option:
opts = {:environment => :dev}
JerbilService::Client.find_services(:all, MyService, opts) do ...
If you want to use a config file to access this information, you can use get_config and extract the env information:
config = JerbilService::Client.get_config(MyService)
opts[:environment] = config[:environment]
...
The connection to the service is closed when the block exits.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/jerbil/jerbil_service/client.rb', line 105 def self.find_services(what, modl, ={}, &block) case what when :first select = :first when :all select = :all when :local select = :first [:local] = true else raise ArgumentError, "Find Services invalid search key: #{what}" end unless [:environment] # set the default environment if not already set [:environment] = :prod end new(modl, ) do |client| client.connect(select, &block) end end |
.get_config(modl, config_file = nil) ⇒ Object
return the server’s config options for the given file, or the default if none given
This method uses [Jeckyl]() to obtain the config parameters. The module name is expected to follow the guidelines for a JerbilService: create a module with the service’s name (echoed in the gem name etc) and then a class called Service. The parameter passed in is the module name as a constant
config = JerbilService::Client.get_config(MyService)
56 57 58 |
# File 'lib/jerbil/jerbil_service/client.rb', line 56 def self.get_config(modl, config_file=nil) modl.get_config(config_file) end |
Instance Method Details
#connect(index = :all, &block) ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/jerbil/jerbil_service/client.rb', line 224 def connect(index=:all, &block) if index == :first then @session = @services[0].connect @service = @services[0] block.call(self) @session = nil else @services.each do |service| @service = service @session = service.connect block.call(self) end end end |
#host ⇒ String
return the name of the host on which the service is running
259 260 261 |
# File 'lib/jerbil/jerbil_service/client.rb', line 259 def host return @service.host end |
#service_key ⇒ String
return the service key for the given service, which can be used by the caller where a method requires. See Services Readme for details about keys.
268 269 270 |
# File 'lib/jerbil/jerbil_service/client.rb', line 268 def service_key return @service.key end |
#verify ⇒ Boolean
verify that the service is working
This is really a no-op in that if the client has entered the block successfully, then the service that is passed to the block will be working and therefore this call will always return true. Consider it a placebo statement for a client interface that only wants to check the service is running!
251 252 253 |
# File 'lib/jerbil/jerbil_service/client.rb', line 251 def verify @session != nil end |