class Praetor::Service

Attributes

_controllers[R]
redis[RW]

Public Class Methods

controller(klass) click to toggle source
# File lib/praetor/service.rb, line 10
def controller(klass)
  klass.include ServiceController
  (@_controllers ||= []) << klass
end
endpoint() click to toggle source
# File lib/praetor/service.rb, line 15
def endpoint
  @endpoint ||= name.underscore
end

Public Instance Methods

dispatch!(request) click to toggle source
# File lib/praetor/service.rb, line 36
def dispatch!(request)
  controller = request['controller']
  action     = request['action']
  params     = request['params'] || {}

  check_controller! controller

  klass = controller.constantize
  check_action! klass, action

  instance = klass.new
  instance.instance_variable_set :@params, params
  instance.send action
end
run() click to toggle source
# File lib/praetor/service.rb, line 22
def run
  client_options = ENV['REDIS_PROVIDER'] ? { url: ENV['REDIS_PROVIDER'] } : {}
  @redis = Redis.new client_options

  loop do
    # Pop off the next request (or block until one arrives)
    _, request = @redis.brpop self.class.endpoint

    # You can shut down a service by issuing a stop command; useful for testing
    break if request == 'stop'
    handle_request JSON.parse(request)
  end
end

Private Instance Methods

check_action!(controller, action) click to toggle source
# File lib/praetor/service.rb, line 59
def check_action!(controller, action)
  unless controller.method_defined? action
    raise "No action `#{action}` for controller `#{controller}`"
  end
end
check_controller!(controller) click to toggle source
# File lib/praetor/service.rb, line 53
def check_controller!(controller)
  unless self.class._controllers.map(&:name).include? controller
    raise "No controller that matches `#{controller}`"
  end
end
handle_request(request) click to toggle source
# File lib/praetor/service.rb, line 65
def handle_request(request)
  response = begin
    data = dispatch! request
    { 'status' => 'ok', 'data' => data }
  rescue Exception => e
    {
      'status' => 'error',
      'data'   => { 'message' => e.message, 'backtrace' => e.backtrace }
    }
  end

  respond response.merge('key' => request['key'])
end
respond(response) click to toggle source
# File lib/praetor/service.rb, line 79
def respond(response)
  # Push the response onto a new list using the request/response key
  @redis.rpush response['key'], JSON.generate(response)

  # Set an expire time for our list to make sure we don't leak
  @redis.expire response['key'], 30
end