Class: Grumlin::RequestDispatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/grumlin/request_dispatcher.rb

Defined Under Namespace

Classes: DispatcherError, RequestAlreadyAddedError, UnknownRequestError

Constant Summary collapse

SUCCESS =
{
  200 => :success,
  204 => :no_content,
  206 => :partial_content
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRequestDispatcher

Returns a new instance of RequestDispatcher.



18
19
20
# File 'lib/grumlin/request_dispatcher.rb', line 18

def initialize
  @requests = {}
end

Instance Attribute Details

#requestsObject (readonly)

Returns the value of attribute requests.



4
5
6
# File 'lib/grumlin/request_dispatcher.rb', line 4

def requests
  @requests
end

Instance Method Details

#add_request(request) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/grumlin/request_dispatcher.rb', line 22

def add_request(request)
  raise RequestAlreadyAddedError if @requests.include?(request[:requestId])

  Async::Channel.new.tap do |channel|
    @requests[request[:requestId]] = { request:, result: [], channel: }
  end
end

#add_response(response) ⇒ Object

builds a response object, when it’s ready sends it to the client via a channel TODO: sometimes response does not include requestID, no idea how to handle it so far.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/grumlin/request_dispatcher.rb', line 32

def add_response(response) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  request_id = response[:requestId]
  raise UnknownRequestError unless ongoing_request?(request_id)

  begin
    request = @requests[request_id]

    Grumlin::RequestErrorFactory.build(request, response).tap do |err|
      raise err unless err.nil?
    end

    case SUCCESS[response.dig(:status, :code)]
    when :success
      request[:result] << response.dig(:result, :data)
      request[:channel] << request[:result]
      close_request(request_id)
    when :partial_content then request[:result] << response.dig(:result, :data)
    when :no_content
      request[:channel] << []
      close_request(request_id)
    end
  rescue StandardError => e
    request[:channel].exception(e)
    close_request(request_id)
  end
end

#clearObject



63
64
65
66
67
68
# File 'lib/grumlin/request_dispatcher.rb', line 63

def clear
  @requests.each_value do |request|
    request[:channel].close!
  end
  @requests.clear
end

#ongoing_request?(request_id) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/grumlin/request_dispatcher.rb', line 59

def ongoing_request?(request_id)
  @requests.include?(request_id)
end