Class: Elaios::Responder

Inherits:
Object
  • Object
show all
Defined in:
lib/elaios/responder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Responder

Returns a new instance of Responder.



4
5
6
7
8
9
10
11
12
13
14
# File 'lib/elaios/responder.rb', line 4

def initialize(options={})
  @name = options[:name] || 'elaios_server'
  @logger = options[:logger] || Logger.new(STDOUT).tap { |l|
    l.progname = @name
    l.level = ENV['LOG_LEVEL'] || 'info'
  }
  @blocks = {}
  @in = Simple::Queue.new
  @out = Simple::Queue.new
  @mutex = Mutex.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, &block) ⇒ Object

Set up a handler.



35
36
37
38
# File 'lib/elaios/responder.rb', line 35

def method_missing(name, &block)
  @blocks[name] = block
  @logger.debug(%(registered handler for #{name}: #{block.inspect}))
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



2
3
4
# File 'lib/elaios/responder.rb', line 2

def logger
  @logger
end

Instance Method Details

#err(method, id, data) ⇒ Object Also known as: error

Send an error response to the client.



54
55
56
57
58
59
60
61
62
63
# File 'lib/elaios/responder.rb', line 54

def err(method, id, data)
  payload = JSON.dump({
    'jsonrpc' => '2.0',
    'method' => method,
    'error' => data,
    'id' => id
  })
  @logger.debug(%(enqueueing error payload for sending: #{payload.inspect}))
  @out << payload
end

#popObject Also known as: deq, shift



22
23
24
# File 'lib/elaios/responder.rb', line 22

def pop
  @mutex.synchronize { unsafe_pop }
end

#process(obj) ⇒ Object Also known as: pushpop, push_pop



28
29
30
# File 'lib/elaios/responder.rb', line 28

def process(obj)
  @mutex.synchronize { unsafe_push(obj); unsafe_pop }
end

#push(obj) ⇒ Object Also known as: <<, enq



16
17
18
# File 'lib/elaios/responder.rb', line 16

def push(obj)
  @mutex.synchronize { unsafe_push(obj) }
end

#res(method, id, data) ⇒ Object Also known as: response

Send a success response to the client.



41
42
43
44
45
46
47
48
49
50
# File 'lib/elaios/responder.rb', line 41

def res(method, id, data)
  payload = JSON.dump({
    'jsonrpc' => '2.0',
    'method' => method,
    'result' => data,
    'id' => id
  })
  @logger.debug(%(enqueueing success payload for sending: #{payload.inspect}))
  @out << payload
end

#unsafe_popObject

Called internally by ‘pop` and `process`. Exposed for testing.



90
91
92
# File 'lib/elaios/responder.rb', line 90

def unsafe_pop
  @out.pop
end

#unsafe_push(obj) ⇒ Object

Called internally by ‘push` and `process`. Exposed for testing.



84
85
86
87
# File 'lib/elaios/responder.rb', line 84

def unsafe_push(obj)
  @in.push(obj)
  update
end

#updateObject

Called internally by ‘push`. Exposed for testing.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/elaios/responder.rb', line 67

def update
  results = @in.pop
  return unless results
  results.split("\n").each do |result|
    @logger.debug(%(result given: #{result}))
    payload = JSON.load(result) rescue nil
    next unless payload
    @logger.debug(%(payload parsed: #{payload.inspect}))
    block = @blocks[payload['method'].to_sym]
    @logger.debug(%(block found: #{block.inspect}))
    next unless block
    self.instance_exec(payload, &block)
    @logger.debug(%(block called: #{block.inspect}))
  end
end