amqp-client 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83f84f34aa2aacb3719e300483d4a874bc54892e12165b74f895a7503fd3c550
4
- data.tar.gz: b53ba2a5bdbb1620f839f2cca8d66c1ee3db13549360b04e51d018208c1f7b49
3
+ metadata.gz: 30006ba97b26d7e73cf9503841e2248744db3d9e86d1a32fe4c9abecd9ee69f7
4
+ data.tar.gz: a59d667d971da49c2657e57efe385853adbef958fd191a01f0d1f4dbaaa1b8a8
5
5
  SHA512:
6
- metadata.gz: 62aa1fddfbc285ab34e52b3f0421c2a017e157a1e4e6d7c887da78f55c56bb4717a4466bf0ad1ee08a03b485dd55910d38a1b6809d35e373eda1eb248e4cdd33
7
- data.tar.gz: e60e191045e97a268faceb9e3a8112458aa920307e0bf29cdf0d24194c10b0c4254794ab335995019c7b3b41a2fafc383aaee1736584cd618684f6044d760f15
6
+ metadata.gz: 7ddb8f409abf9e773a6551ff53629b702e8324ea7ff794f6b14f09ef9dd7cb27a752e853bb312a8d9da88b826a7714e84006d5bb01b5efeef7bbaed56f14323a
7
+ data.tar.gz: 642e332c0a031d27d7f364b66e0ae5beefef4bad402336f24052eef2679e306eec219369d7b8b2c1d8324eabafd0c40d45aa8feb474c3cd11ddc4578203f5bea
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2021-08-20
4
+
5
+ - Channel#wait_for_confirms is a smarter way of waiting for publish confirms
6
+ - Default connection_name to $PROGRAM_NAME
3
7
 
4
8
  ## [0.2.3] - 2021-08-19
5
9
 
@@ -6,15 +6,16 @@ module AMQP
6
6
  # AMQP Channel
7
7
  class Channel
8
8
  def initialize(connection, id)
9
- @replies = ::Queue.new
10
9
  @connection = connection
11
10
  @id = id
11
+ @replies = ::Queue.new
12
12
  @consumers = {}
13
- @confirm = nil
14
- @last_confirmed = 0
15
13
  @closed = nil
16
- @on_return = nil
17
14
  @open = false
15
+ @on_return = nil
16
+ @confirm = nil
17
+ @unconfirmed = ::Queue.new
18
+ @unconfirmed_empty = ::Queue.new
18
19
  end
19
20
 
20
21
  attr_reader :id, :consumers
@@ -124,15 +125,17 @@ module AMQP
124
125
  def basic_publish(body, exchange, routing_key, **properties)
125
126
  frame_max = @connection.frame_max - 8
126
127
  id = @id
128
+ mandatory = properties.delete(:mandatory) || false
127
129
 
128
130
  if 0 < body.bytesize && body.bytesize <= frame_max
129
- write_bytes FrameBytes.basic_publish(id, exchange, routing_key, properties.delete(:mandatory) || false),
131
+ write_bytes FrameBytes.basic_publish(id, exchange, routing_key, mandatory),
130
132
  FrameBytes.header(id, body.bytesize, properties),
131
133
  FrameBytes.body(id, body)
132
- return @confirm ? @confirm += 1 : nil
134
+ @unconfirmed.push @confirm += 1 if @confirm
135
+ return
133
136
  end
134
137
 
135
- write_bytes FrameBytes.basic_publish(id, exchange, routing_key, properties.delete(:mandatory) || false),
138
+ write_bytes FrameBytes.basic_publish(id, exchange, routing_key, mandatory),
136
139
  FrameBytes.header(id, body.bytesize, properties)
137
140
  pos = 0
138
141
  while pos < body.bytesize # split body into multiple frame_max frames
@@ -141,13 +144,14 @@ module AMQP
141
144
  write_bytes FrameBytes.body(id, body_part)
142
145
  pos += len
143
146
  end
144
- @confirm += 1 if @confirm
147
+ @unconfirmed.push @confirm += 1 if @confirm
148
+ nil
145
149
  end
146
150
 
147
151
  def basic_publish_confirm(body, exchange, routing_key, **properties)
148
152
  confirm_select(no_wait: true)
149
- id = basic_publish(body, exchange, routing_key, **properties)
150
- wait_for_confirm(id)
153
+ basic_publish(body, exchange, routing_key, **properties)
154
+ wait_for_confirms
151
155
  end
152
156
 
153
157
  # Consume from a queue
@@ -211,20 +215,32 @@ module AMQP
211
215
 
212
216
  write_bytes FrameBytes.confirm_select(@id, no_wait)
213
217
  expect :confirm_select_ok unless no_wait
214
- @confirms = ::Queue.new
215
218
  @confirm = 0
216
219
  end
217
220
 
218
- def wait_for_confirm(id)
219
- raise ArgumentError, "Confirm id has to a positive number" unless id&.positive?
220
- return true if @last_confirmed >= id
221
+ # Block until all publishes messages are confirmed
222
+ def wait_for_confirms
223
+ return true if @unconfirmed.empty?
224
+
225
+ @unconfirmed_empty.pop
226
+ end
221
227
 
228
+ def confirm(args)
229
+ ack_or_nack, delivery_tag, multiple = *args
222
230
  loop do
223
- ack, delivery_tag, multiple = @confirms.shift || break
224
- @last_confirmed = delivery_tag
225
- return ack if delivery_tag == id || (delivery_tag > id && multiple)
231
+ tag = @unconfirmed.pop(true)
232
+ break if tag == delivery_tag
233
+ next if multiple && tag < delivery_tag
234
+
235
+ @unconfirmed << tag # requeue
236
+ rescue ThreadError
237
+ break
238
+ end
239
+ return unless @unconfirmed.empty?
240
+
241
+ @unconfirmed_empty.num_waiting.times do
242
+ @unconfirmed_empty << ack_or_nack == :ack
226
243
  end
227
- false
228
244
  end
229
245
 
230
246
  def tx_select
@@ -246,10 +262,6 @@ module AMQP
246
262
  @replies.push(args)
247
263
  end
248
264
 
249
- def confirm(args)
250
- @confirms.push(args)
251
- end
252
-
253
265
  def message_returned(reply_code, reply_text, exchange, routing_key)
254
266
  Thread.new do
255
267
  body_size, properties = expect(:header)
@@ -164,7 +164,8 @@ module AMQP
164
164
  channel = @channels.delete(channel_id)
165
165
  channel.closed!(reply_code, reply_text, classid, methodid)
166
166
  when 41 # channel#close-ok
167
- @channels[channel_id].reply [:channel_close_ok]
167
+ channel = @channels.delete(channel_id)
168
+ channel.reply [:channel_close_ok]
168
169
  else raise AMQP::Client::UnsupportedMethodFrame, class_id, method_id
169
170
  end
170
171
  when 40 # exchange
@@ -263,10 +264,7 @@ module AMQP
263
264
  @channels[channel_id].reply [:basic_get_empty]
264
265
  when 80 # ack
265
266
  delivery_tag, multiple = buf.unpack("@11 Q> C")
266
- @channels[channel_id].confirm [:ack, delivery_tag, multiple]
267
- when 90 # reject
268
- delivery_tag, requeue = buf.unpack("@11 Q> C")
269
- @channels[channel_id].confirm [:reject, delivery_tag, requeue == 1]
267
+ @channels[channel_id].confirm [:ack, delivery_tag, multiple == 1]
270
268
  when 111 # recover-ok
271
269
  @channels[channel_id].reply [:basic_recover_ok]
272
270
  when 120 # nack
@@ -334,7 +332,8 @@ module AMQP
334
332
 
335
333
  case method_id
336
334
  when 10 # connection#start
337
- properties = CLIENT_PROPERTIES.merge({ connection_name: options[:connection_name] })
335
+ conn_name = options[:connection_name] || $PROGRAM_NAME
336
+ properties = CLIENT_PROPERTIES.merge({ connection_name: conn_name })
338
337
  socket.write FrameBytes.connection_start_ok "\u0000#{user}\u0000#{password}", properties
339
338
  when 30 # connection#tune
340
339
  channel_max, frame_max, heartbeat = buf.unpack("@11 S> L> S>")
@@ -69,7 +69,8 @@ module AMQP
69
69
  end
70
70
 
71
71
  if expiration
72
- expiration.is_a?(String) || raise(ArgumentError, "expiration must be a string")
72
+ expiration = expiration.to_s if expiration.is_a?(Integer)
73
+ expiration.is_a?(String) || raise(ArgumentError, "expiration must be a string or integer")
73
74
 
74
75
  flags |= (1 << 8)
75
76
  arr << expiration.bytesize << expiration
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AMQP
4
4
  class Client
5
- VERSION = "0.2.3"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amqp-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Hörberg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-19 00:00:00.000000000 Z
11
+ date: 2021-08-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Work in progress
14
14
  email: