Class: KubeMQ::Queues::DownstreamReceiver
- Inherits:
-
Object
- Object
- KubeMQ::Queues::DownstreamReceiver
- Defined in:
- lib/kubemq/queues/downstream_receiver.rb
Overview
This class is thread-safe. Multiple threads may call #poll concurrently; each waits independently for its response.
Streaming receiver for queue messages over a persistent gRPC downstream.
Created via KubeMQ::QueuesClient#create_downstream_receiver. Keeps a bidirectional stream open for polling with transactional acknowledgement. Call #poll to receive messages and use the returned QueuePollResponse for batch or per-message actions.
Constant Summary collapse
- RESPONSE_TIMEOUT =
Maximum seconds to wait for a downstream response.
60
Instance Method Summary collapse
-
#close ⇒ void
Closes the receiver and its underlying gRPC stream.
-
#initialize(transport:, client_id:) ⇒ DownstreamReceiver
constructor
private
A new instance of DownstreamReceiver.
-
#poll(request) ⇒ QueuePollResponse
Polls the queue channel for messages.
-
#send_action(transaction_id:, type:, channel: nil, sequence_range: []) ⇒ Object?
private
Sends a transaction action over the downstream stream.
Constructor Details
#initialize(transport:, client_id:) ⇒ DownstreamReceiver
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of DownstreamReceiver.
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/kubemq/queues/downstream_receiver.rb', line 27 def initialize(transport:, client_id:) @transport = transport @client_id = client_id @request_queue = Queue.new @pending = {} @pending_mutex = Mutex.new @mutex = Mutex.new @closed = false @stream_alive = true @stream_error = nil start_stream! end |
Instance Method Details
#close ⇒ void
This method returns an undefined value.
Closes the receiver and its underlying gRPC stream.
Sends a close-by-client request to the broker and shuts down the stream. This method is idempotent — calling it multiple times is safe.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/kubemq/queues/downstream_receiver.rb', line 118 def close @mutex.synchronize do return if @closed @closed = true end wake_all_pending! begin close_request = ::Kubemq::QueuesDownstreamRequest.new( RequestID: SecureRandom.uuid, ClientID: @client_id, RequestTypeData: :CloseByClient ) @request_queue.push(close_request) sleep(0.5) rescue StandardError # best-effort end @request_queue.push(:close) @stream_thread&.join(5) end |
#poll(request) ⇒ QueuePollResponse
Polls the queue channel for messages.
Blocks until messages arrive or the request's wait_timeout elapses.
Returns a QueuePollResponse with received messages and transaction
action methods.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/kubemq/queues/downstream_receiver.rb', line 56 def poll(request) raise ClientClosedError if @mutex.synchronize { @closed } unless @mutex.synchronize { @stream_alive } raise StreamBrokenError.new( 'Queue downstream stream is broken', cause: @mutex.synchronize { @stream_error } ) end Validator.validate_channel!(request.channel, allow_wildcards: false) Validator.validate_queue_poll!(request.max_items, request.wait_timeout) request_id = SecureRandom.uuid proto_request = ::Kubemq::QueuesDownstreamRequest.new( RequestID: request_id, ClientID: @client_id, RequestTypeData: :Get, Channel: request.channel, MaxItems: request.max_items, WaitTimeout: request.wait_timeout * 1000, AutoAck: request.auto_ack ) timeout = [request.wait_timeout + 5, RESPONSE_TIMEOUT].min response = send_and_wait(request_id, proto_request, timeout) raise TimeoutError, 'Queue poll timed out' unless response build_poll_response(response) end |
#send_action(transaction_id:, type:, channel: nil, sequence_range: []) ⇒ Object?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Sends a transaction action over the downstream stream.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/kubemq/queues/downstream_receiver.rb', line 96 def send_action(transaction_id:, type:, channel: nil, sequence_range: []) raise ClientClosedError, 'Downstream receiver is closed' if @mutex.synchronize { @closed } request_id = SecureRandom.uuid proto_request = ::Kubemq::QueuesDownstreamRequest.new( RequestID: request_id, ClientID: @client_id, RequestTypeData: type, RefTransactionId: transaction_id, ReQueueChannel: channel || '', SequenceRange: sequence_range ) send_and_wait(request_id, proto_request, 10) end |