amqp-client 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AMQP
4
+ class Client
5
+ # Reusable RPC client, when RPC performance is important
6
+ class RPCClient
7
+ # @param channel [AMQP::Client::Connection::Channel] the channel to use for the RPC calls
8
+ def initialize(channel)
9
+ @ch = channel
10
+ @correlation_id = 0
11
+ @lock = Mutex.new
12
+ @messages = ::Queue.new
13
+ end
14
+
15
+ # Start listening for responses from the RPC calls
16
+ # @return [self]
17
+ def start
18
+ @ch.basic_consume("amq.rabbitmq.reply-to") do |msg|
19
+ @messages.push msg
20
+ end
21
+ self
22
+ end
23
+
24
+ # Do a RPC call, sends a messages, waits for a response
25
+ # @param method [String, Symbol] name of the method to call (i.e. queue name on the server side)
26
+ # @param arguments [String] arguments/body to the call
27
+ # @param timeout [Numeric, nil] Number of seconds to wait for a response
28
+ # @option (see Client#publish)
29
+ # @raise [Timeout::Error] if no response is received within the timeout period
30
+ # @return [String] Returns the result from the call
31
+ def call(method, arguments, timeout: nil, **properties)
32
+ correlation_id = @lock.synchronize { @correlation_id += 1 }.to_s(36)
33
+ @ch.basic_publish(arguments, exchange: "", routing_key: method.to_s,
34
+ reply_to: "amq.rabbitmq.reply-to", correlation_id:, **properties)
35
+ Timeout.timeout(timeout) do # Timeout the whole loop if we never find the right correlation_id
36
+ loop do
37
+ msg = @messages.pop(timeout:) # Timeout individual pop to avoid blocking forever
38
+ raise Timeout::Error if msg.nil? && timeout
39
+
40
+ return msg.body if msg.properties.correlation_id == correlation_id
41
+
42
+ @messages.push msg
43
+ end
44
+ end
45
+ rescue Timeout::Error
46
+ raise Timeout::Error, "No response received in #{timeout} seconds"
47
+ end
48
+
49
+ # Closes the channel used by the RPCClient
50
+ def close
51
+ @ch.close
52
+ @messages.close
53
+ end
54
+ end
55
+ end
56
+ end
@@ -9,7 +9,7 @@ module AMQP
9
9
  # @param hash [Hash]
10
10
  # @return [String] Byte array
11
11
  def self.encode(hash)
12
- return "" if hash.empty?
12
+ return "" if hash.nil? || hash.empty?
13
13
 
14
14
  arr = []
15
15
  fmt = String.new
@@ -136,7 +136,7 @@ module AMQP
136
136
  scale = bytes.getbyte(pos)
137
137
  pos += 1
138
138
  value = bytes.byteslice(pos, 4).unpack1("L>")
139
- d = value / 10**scale
139
+ d = value / (10**scale)
140
140
  [5, d]
141
141
  when "x"
142
142
  len = bytes.byteslice(pos, 4).unpack1("L>")
@@ -3,6 +3,6 @@
3
3
  module AMQP
4
4
  class Client
5
5
  # Version of the client library
6
- VERSION = "1.2.0"
6
+ VERSION = "2.0.0"
7
7
  end
8
8
  end