twingly-amqp 5.0.1 → 6.0.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: c61cf032af90e6b91d1c690ad02f89c6a46e3cc7879813e47f1ee89a1367609a
4
- data.tar.gz: 6508f9911ef9dcb8c64854522915129878905e62620dbf022ec104e8a911354a
3
+ metadata.gz: 2cfce02de5ea28c844564b13473a31afd438dbc2001392092902666da3a8721a
4
+ data.tar.gz: 05db74046a863f23a0e541cc60402e0f3ae91e5ca6e01131e8aa16c0cc15fc29
5
5
  SHA512:
6
- metadata.gz: 0f66b4eda7c713585780fa20f1bae2948b3251f00929f16fd01273f3298a32fb921eaa334e5814f464eac85446bdc17be227e9f850293a0bb753131f061a6f37
7
- data.tar.gz: 87c30a0c5e817ea29be19da7b99e3d156f4ba6ca303abd63ebb265827673c90ac3b64ca22bd9d3e5df355163fb29b888931e41d6637282460d598c2bff4114b4
6
+ metadata.gz: 556a43b0b4229225828678fe9f23f3912e39e7a8ec72f6fd2a549cfbd6db7dfa6043aa1f3e0f23998a5fea38f329fb110a3904db84ddd16a8657aad21a3a2d1a
7
+ data.tar.gz: fb0b7fa69facd940accfabbab125ae116d20101f9e33e87b010087d800687c21953a52983035c66bcc95e58fae2ba0ba78b529ba7d398680b56e405129d82b19
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Twingly::AMQP
2
2
 
3
- [![Build Status](https://travis-ci.org/twingly/twingly-amqp.svg?branch=master)](https://travis-ci.org/twingly/twingly-amqp)
4
-
3
+ [![GitHub Build Status](https://github.com/twingly/twingly-amqp/workflows/CI/badge.svg?branch=master)](https://github.com/twingly/twingly-amqp/actions)
5
4
 
6
5
  A gem for subscribing and publishing messages via RabbitMQ.
7
6
 
@@ -60,6 +59,8 @@ subscription = Twingly::AMQP::Subscription.new(
60
59
  consumer_threads: 4, # Optional
61
60
  prefetch: 20, # Optional
62
61
  max_length: 10_000, # Optional
62
+ queue_type: :quorum, # Optional, which type of queue to create,
63
+ # possible values are :quorum (default) or :classic
63
64
  )
64
65
 
65
66
  subscription.on_exception { |exception| puts "Oh noes! #{exception.message}" }
@@ -133,6 +134,24 @@ end
133
134
  publisher.publish({ my: "data" })
134
135
  ```
135
136
 
137
+ ### Publish delayed messages
138
+
139
+ ```ruby
140
+ publisher = Twingly::AMQP::DefaultExchangePublisher.delayed(
141
+ delay_queue_name: "my_queue.delayed", # Queue where delayed messages will
142
+ # wait until delay_ms has passed
143
+ target_queue_name: "my_queue", # Queue which delayed messages will be
144
+ # published to after the delay has elapsed
145
+ delay_ms: 60_000,
146
+ delay_queue_type: :quorum, # Optional. Which type of queue to define the delay queue
147
+ # as. Possible values are :quorum (default) or :classic
148
+ )
149
+
150
+ # Publishes message to the delay queue. After delay_ms has passed,
151
+ # the message will be rerouted to the target queue specified above
152
+ publisher.publish({ my: "data" })
153
+ ```
154
+
136
155
  ### Ping urls
137
156
 
138
157
  ```ruby
@@ -199,6 +218,12 @@ connection = Twingly::AMQP::Connection.instance
199
218
 
200
219
  The integration tests run by default and require a local RabbitMQ server to run.
201
220
 
221
+ Start RabbitMQ server with
222
+
223
+ ```shell
224
+ docker-compose up
225
+ ```
226
+
202
227
  Run tests with
203
228
 
204
229
  ```shell
@@ -230,7 +255,7 @@ To run static code analysis:
230
255
 
231
256
  bundle exec rake release
232
257
 
233
- * If you are not logged in as [twingly][twingly-rubygems] with ruby gems, the rake task will fail and tell you to set credentials via `gem push`, do that and run the `release` task again. It will be okay.
258
+ * If you are not logged in as [twingly][twingly-rubygems] with ruby gems, the rake task will fail. Login using `gem signin` and run the `release` task again. It will be okay.
234
259
 
235
260
  * Update the changelog with [GitHub Changelog Generator](https://github.com/skywinder/github-changelog-generator/) (`gem install github_changelog_generator` if you don't have it, set `CHANGELOG_GITHUB_TOKEN` to a personal access token to avoid rate limiting by GitHub). This command will update `CHANGELOG.md`, commit and push manually.
236
261
 
@@ -1,5 +1,3 @@
1
- require "twingly/amqp"
2
-
3
1
  module Twingly
4
2
  module AMQP
5
3
  class Connection
@@ -1,17 +1,31 @@
1
- require "twingly/amqp/publisher"
2
- require "twingly/amqp/connection"
3
-
4
1
  module Twingly
5
2
  module AMQP
6
3
  class DefaultExchangePublisher
7
4
  include Publisher
8
5
 
9
- def initialize(queue_name:, connection: nil)
6
+ DEFAULT_EXCHANGE = ""
7
+
8
+ def initialize(queue_name:, connection: Connection.instance)
10
9
  options.routing_key = queue_name
11
10
 
12
- connection ||= Connection.instance
13
11
  @exchange = connection.create_channel.default_exchange
14
12
  end
13
+
14
+ def self.delayed(delay_queue_name:, target_queue_name:, delay_ms:, delay_queue_type: :quorum,
15
+ connection: Connection.instance)
16
+ Utilities.create_queue(delay_queue_name,
17
+ arguments: {
18
+ "x-dead-letter-exchange": DEFAULT_EXCHANGE,
19
+ "x-dead-letter-routing-key": target_queue_name,
20
+ },
21
+ queue_type: delay_queue_type)
22
+
23
+ new(queue_name: delay_queue_name, connection: connection).tap do |publisher|
24
+ publisher.configure_publish_options do |options|
25
+ options.expiration = delay_ms
26
+ end
27
+ end
28
+ end
15
29
  end
16
30
  end
17
31
  end
@@ -1,5 +1,3 @@
1
- require "json"
2
-
3
1
  module Twingly
4
2
  module AMQP
5
3
  class Message
@@ -1,14 +1,8 @@
1
- require "twingly/amqp/connection"
2
- require "twingly/amqp/ping_options"
3
- require "twingly/amqp/default_exchange_publisher"
4
- require "json"
5
-
6
1
  module Twingly
7
2
  module AMQP
8
3
  class Pinger
9
- def initialize(queue_name:, ping_expiration: nil, url_cache: NullCache, connection: nil, confirm_publish: false)
4
+ def initialize(queue_name:, ping_expiration: nil, url_cache: NullCache, connection: Connection.instance, confirm_publish: false)
10
5
  @url_cache = url_cache
11
- connection ||= Connection.instance
12
6
 
13
7
  @publisher = DefaultExchangePublisher.new(queue_name: queue_name, connection: connection)
14
8
  @publisher.configure_publish_options do |options|
@@ -1,6 +1,3 @@
1
- require "json"
2
- require "ostruct"
3
-
4
1
  module Twingly
5
2
  module AMQP
6
3
  module Publisher
@@ -19,7 +16,7 @@ module Twingly
19
16
  @exchange.publish(json_payload, opts)
20
17
  end
21
18
 
22
- # only used by tests to avoid sleeping
19
+ # Only used by tests to lessen the time we need to sleep
23
20
  def publish_with_confirm(message)
24
21
  channel = @exchange.channel
25
22
  channel.confirm_select unless channel.using_publisher_confirmations?
@@ -1,5 +1,3 @@
1
- require "bunny"
2
-
3
1
  module Twingly
4
2
  module AMQP
5
3
  class Session
@@ -1,27 +1,28 @@
1
- require "twingly/amqp/connection"
2
- require "twingly/amqp/message"
3
-
4
1
  module Twingly
5
2
  module AMQP
6
3
  class Subscription
7
4
  def initialize(queue_name:, exchange_topic: nil, routing_key: nil,
8
5
  routing_keys: nil, consumer_threads: 1, prefetch: 20,
9
- connection: nil, max_length: nil)
6
+ connection: Connection.instance, max_length: nil,
7
+ queue_type: :quorum)
10
8
  @queue_name = queue_name
11
9
  @exchange_topic = exchange_topic
12
10
  @routing_keys = Array(routing_keys || routing_key)
13
11
  @consumer_threads = consumer_threads
14
12
  @prefetch = prefetch
15
13
  @max_length = max_length
14
+ @queue_type = queue_type
15
+ @cancel = false
16
+ @consumer = nil
17
+ @blocking = false
16
18
 
17
19
  if routing_key
18
20
  warn "[DEPRECATION] `routing_key` is deprecated. "\
19
21
  "Please use `routing_keys` instead."
20
22
  end
21
23
 
22
- connection ||= Connection.instance
23
24
  @channel = create_channel(connection)
24
- @queue = @channel.queue(@queue_name, queue_options)
25
+ @queue = create_queue
25
26
 
26
27
  if @exchange_topic && @routing_keys.any?
27
28
  exchange = @channel.topic(@exchange_topic, durable: true)
@@ -36,12 +37,13 @@ module Twingly
36
37
  end
37
38
 
38
39
  def each_message(blocking: true, &block)
39
- consumer = create_consumer(&block)
40
+ @blocking = blocking
41
+ @consumer = create_consumer(&block)
40
42
 
41
- if blocking
43
+ if @blocking
42
44
  sleep 0.01 until cancel?
43
45
 
44
- consumer.cancel
46
+ @consumer.cancel
45
47
  end
46
48
  end
47
49
 
@@ -66,6 +68,7 @@ module Twingly
66
68
  end
67
69
 
68
70
  def cancel!
71
+ @consumer.cancel unless @blocking
69
72
  @cancel = true
70
73
  end
71
74
 
@@ -96,6 +99,17 @@ module Twingly
96
99
  channel
97
100
  end
98
101
 
102
+ def create_queue
103
+ case @queue_type
104
+ when :quorum
105
+ @channel.quorum_queue(@queue_name, queue_options)
106
+ when :classic
107
+ @channel.queue(@queue_name, queue_options)
108
+ else
109
+ raise ArgumentError, "Unknown queue type #{@queue_type}"
110
+ end
111
+ end
112
+
99
113
  def queue_options
100
114
  {
101
115
  durable: true,
@@ -1,15 +1,11 @@
1
- require "twingly/amqp/publisher"
2
- require "twingly/amqp/connection"
3
-
4
1
  module Twingly
5
2
  module AMQP
6
3
  class TopicExchangePublisher
7
4
  include Publisher
8
5
 
9
- def initialize(exchange_name:, routing_key: nil, connection: nil, opts: {})
6
+ def initialize(exchange_name:, routing_key: nil, connection: Connection.instance, opts: {})
10
7
  options.routing_key = routing_key
11
8
 
12
- connection ||= Connection.instance
13
9
  @exchange = connection.create_channel.topic(exchange_name, opts)
14
10
  end
15
11
  end
@@ -0,0 +1,21 @@
1
+ module Twingly
2
+ module AMQP
3
+ module Utilities
4
+ def self.create_queue(queue_name, durable: true, arguments: {}, queue_type: :quorum, connection: Connection.instance)
5
+ connection.with_channel do |channel|
6
+ case queue_type
7
+ when :quorum
8
+ # Quorum queues are always durable, see https://www.rabbitmq.com/quorum-queues.html#feature-matrix
9
+ raise ArgumentError, "durable: false is not supported by quorum queues" unless durable
10
+
11
+ return channel.quorum_queue(queue_name, arguments: arguments)
12
+ when :classic
13
+ return channel.queue(queue_name, durable: durable, arguments: arguments)
14
+ else
15
+ raise ArgumentError, "Unknown queue type '#{queue_type}'"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  module Twingly
2
2
  module Amqp
3
- VERSION = "5.0.1".freeze
3
+ VERSION = "6.0.0".freeze
4
4
  end
5
5
  end
data/lib/twingly/amqp.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "twingly/amqp/version"
2
2
  require "twingly/amqp/session"
3
3
  require "twingly/amqp/connection"
4
+ require "twingly/amqp/utilities"
4
5
  require "twingly/amqp/subscription"
5
6
  require "twingly/amqp/ping_options"
6
7
  require "twingly/amqp/pinger"
@@ -8,7 +9,10 @@ require "twingly/amqp/publisher"
8
9
  require "twingly/amqp/default_exchange_publisher"
9
10
  require "twingly/amqp/topic_exchange_publisher"
10
11
  require "twingly/amqp/null_logger"
12
+ require "twingly/amqp/message"
11
13
 
14
+ require "bunny"
15
+ require "json"
12
16
  require "ostruct"
13
17
 
14
18
  module Twingly
metadata CHANGED
@@ -1,35 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twingly-amqp
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Twingly AB
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-09 00:00:00.000000000 Z
11
+ date: 2023-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.6'
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
- version: 2.6.2
19
+ version: 2.20.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '2.6'
30
24
  - - ">="
31
25
  - !ruby/object:Gem::Version
32
- version: 2.6.2
26
+ version: 2.20.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rake
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -77,6 +71,7 @@ files:
77
71
  - lib/twingly/amqp/session.rb
78
72
  - lib/twingly/amqp/subscription.rb
79
73
  - lib/twingly/amqp/topic_exchange_publisher.rb
74
+ - lib/twingly/amqp/utilities.rb
80
75
  - lib/twingly/amqp/version.rb
81
76
  homepage: https://github.com/twingly/twingly-amqp
82
77
  licenses: []
@@ -96,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
91
  - !ruby/object:Gem::Version
97
92
  version: '0'
98
93
  requirements: []
99
- rubygems_version: 3.1.2
94
+ rubygems_version: 3.4.4
100
95
  signing_key:
101
96
  specification_version: 4
102
97
  summary: Ruby library for talking to RabbitMQ