Class: Zack::Server
- Inherits:
-
Object
- Object
- Zack::Server
- Defined in:
- lib/zack/server.rb
Overview
Server side for RPC calls.
Instance Attribute Summary collapse
-
#factory ⇒ Object
readonly
Returns the value of attribute factory.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#service ⇒ Object
readonly
Returns the value of attribute service.
Instance Method Summary collapse
-
#handle_request(exception_handler = nil) ⇒ Object
Handles exactly one request.
-
#initialize(tube_name, opts = {}) ⇒ Server
constructor
Initializes a zack server.
-
#process_request(control, sym, args) ⇒ Object
Processes exactly one request, but doesn’t define how the request gets here.
-
#run(messages = nil, &exception_handler) ⇒ Object
Runs the server and keeps running until the world ends (or the process, whichever comes first).
Constructor Details
#initialize(tube_name, opts = {}) ⇒ Server
Initializes a zack server. To specify which class should be the target of the RPC call, you must either give the :factory or the :simple argument.
:simple expects a class. This class will be constructed each time a request is made. Then the method will be called on the class.
:factory expects a callable (a block or something that has #call) and is passed the control object for the request (see Cod for an explanation of this). You can chose to ignore the control and just use the block to produce an object that is linked to the rest of your program. Or you can link to the rest of the program and the control at the same time.
Note that in any case, one object instance _per call_ is created. This is to discourage creating stateful servers. If you still want to do that, well you will just have to code around the limitation, now won’t you.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/zack/server.rb', line 28 def initialize(tube_name, opts={}) @server = opts[:server] if opts.has_key? :factory @factory = opts[:factory] elsif opts.has_key? :simple klass = opts[:simple] @factory = lambda { |ctl| klass.new } else raise ArgumentError, "Either :factory or :simple argument must be given." end channel = Cod.beanstalk(tube_name, server) @service = channel.service end |
Instance Attribute Details
#factory ⇒ Object (readonly)
Returns the value of attribute factory.
7 8 9 |
# File 'lib/zack/server.rb', line 7 def factory @factory end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
8 9 10 |
# File 'lib/zack/server.rb', line 8 def server @server end |
#service ⇒ Object (readonly)
Returns the value of attribute service.
6 7 8 |
# File 'lib/zack/server.rb', line 6 def service @service end |
Instance Method Details
#handle_request(exception_handler = nil) ⇒ Object
Handles exactly one request.
46 47 48 49 50 51 52 53 |
# File 'lib/zack/server.rb', line 46 def handle_request(exception_handler=nil) service.one { |(sym, args), control| exception_handling(exception_handler, control) do # p [sym, args] process_request(control, sym, args) end } end |
#process_request(control, sym, args) ⇒ Object
Processes exactly one request, but doesn’t define how the request gets here.
58 59 60 61 62 |
# File 'lib/zack/server.rb', line 58 def process_request(control, sym, args) instance = factory.call(control) instance.send(sym, *args) end |
#run(messages = nil, &exception_handler) ⇒ Object
Runs the server and keeps running until the world ends (or the process, whichever comes first). If you pass a non-nil messages argument, the server will process that many messages and then quit. (Maybe you will want to respawn the server from time to time?)
Any exception that is raised inside the RPC code will be passed to the exception_handler block:
server.run do |exception, control|
# control is the service control object from cod. You can exercise
# fine grained message control using this.
log.fatal exception
end
If you don’t reraise exceptions from the exception handler block, they will be caught and the server will stay running.
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/zack/server.rb', line 81 def run(=nil, &exception_handler) loop do handle_request(exception_handler) if -= 1 break if <= 0 end end end |