Class: Zack::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/zack/server.rb

Overview

Server side for RPC calls.

Instance Attribute Summary collapse

Instance Method Summary collapse

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.

Note that in any case, one object instance _per call_ is created. This is to discourage creating stateful servers.

Parameters:

  • tube_name (String)

    the tube to communicate with

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :simple (Class)

    class will be constructed for each request. The request will then be handed to the class.

  • :factory (#call)

    factory for request handler instances. One parameter gets passed to this call, the control structure for the beanstalk connection.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/zack/server.rb', line 24

def initialize(tube_name, opts={})
  @server = opts[:server]
  @tube_name = tube_name

  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

  reconnect
end

Instance Attribute Details

#factoryObject (readonly)

Returns the value of attribute factory.



7
8
9
# File 'lib/zack/server.rb', line 7

def factory
  @factory
end

#serverObject (readonly)

Returns the value of attribute server.



8
9
10
# File 'lib/zack/server.rb', line 8

def server
  @server
end

#serviceObject (readonly)

Returns the value of attribute service.



6
7
8
# File 'lib/zack/server.rb', line 6

def service
  @service
end

Instance Method Details

#closeObject

Closes the connection and shuts down the server.



103
104
105
# File 'lib/zack/server.rb', line 103

def close
  @channel.close
end

#handle_request(exception_handler = nil) ⇒ Object

Handles exactly one request.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/zack/server.rb', line 43

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
  }
  
# Reconnect when the connection is lost  
rescue Cod::ConnectionLost
  @channel.close
  reconnect
  
  retry 
end

#process_request(control, sym, args) ⇒ Object

Processes exactly one request, but doesn’t define how the request gets here.



63
64
65
66
67
# File 'lib/zack/server.rb', line 63

def process_request(control, sym, args)
  instance = factory.call(control)

  instance.send(sym, *args)
end

#run(messages = nil) {|Exception, Cod::Beanstalk::Service::Control| ... } ⇒ 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.

Parameters:

  • messages (Number) (defaults to: nil)

    how many messages to process, or nil for endless operation

Yields:

  • (Exception, Cod::Beanstalk::Service::Control)


90
91
92
93
94
95
96
97
98
99
# File 'lib/zack/server.rb', line 90

def run(messages=nil, &exception_handler)
  loop do
    handle_request(exception_handler)

    if messages
      messages -= 1
      break if messages <= 0
    end
  end
end