lepus 0.1.3 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/docs/configuration.md +14 -1
- data/docs/producers.md +30 -2
- data/docs/testing.md +8 -0
- data/gemfiles/Gemfile.rails-5.2.lock +1 -1
- data/gemfiles/Gemfile.rails-6.1.lock +1 -1
- data/gemfiles/Gemfile.rails-7.2.lock +1 -1
- data/gemfiles/Gemfile.rails-8.0.lock +1 -1
- data/lib/lepus/configuration.rb +47 -6
- data/lib/lepus/connection_pool.rb +4 -3
- data/lib/lepus/producer.rb +14 -7
- data/lib/lepus/producers/config.rb +25 -12
- data/lib/lepus/producers/definition.rb +3 -1
- data/lib/lepus/publisher.rb +7 -2
- data/lib/lepus/testing/exchange.rb +2 -0
- data/lib/lepus/testing.rb +5 -0
- data/lib/lepus/version.rb +1 -1
- data/lib/lepus.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67f07eb800872caf73d2f74330322cfb4682f740cf60734405f399f815368a9f
|
|
4
|
+
data.tar.gz: 96257edb75021e9154cef73212e26f450f508ad7aa0fb5659756efebb8b3cb5a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eab85b9d115eade80732103040ca2e0db25e8146e0dc957005e469ec60776f0a0693a59bd5359bc618a1bb69fafd7b8b0ac19502029355703629f1d5a7040e89
|
|
7
|
+
data.tar.gz: 652b48322bb2372a261c497da6e60d4ea218f90d1ea2ae41da32024da74f6c5d4d288a4249af8279825aba6bf20b385748692190c2db871a63ab35e8e4338d78
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 0.2.0 - 2026-10-28
|
|
8
|
+
* Added: named producer connections via `config.connection(name, url:, **bunny_options)`; `rabbitmq_url` remains the `:default` connection
|
|
9
|
+
* Added: `connection:` option on `Producer.configure`, `Producer.publish` and `Lepus::Publisher.new`, with one producer connection pool per name
|
|
10
|
+
* Added: `Lepus::InvalidConnectionError` raised for unregistered connection names
|
|
11
|
+
* Added: fake messages in `Lepus::Testing` record their `connection`
|
|
12
|
+
|
|
7
13
|
## 0.0.1 - 2024-08-01
|
|
8
14
|
The first release of the gem
|
|
9
15
|
* Added: Initial implementation with support to Sidekiq and Faktory backends
|
data/Gemfile.lock
CHANGED
data/docs/configuration.md
CHANGED
|
@@ -28,6 +28,19 @@ end
|
|
|
28
28
|
| `recovery_attempts` | `10` | Max automatic reconnects; `nil` for infinite |
|
|
29
29
|
| `recover_from_connection_close` | `true` | Auto-recover after a clean close |
|
|
30
30
|
|
|
31
|
+
### Named connections
|
|
32
|
+
|
|
33
|
+
Producers can publish to more than one broker. Register extra brokers by name; `rabbitmq_url` stays the `:default` connection and remains the only one used by consumers, the supervisor, the process registry and the web dashboard.
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
Lepus.configure do |config|
|
|
37
|
+
config.rabbitmq_url = ENV.fetch('RABBITMQ_URL')
|
|
38
|
+
config.connection(:replica, url: ENV.fetch('REPLICA_RABBITMQ_URL'), recovery_attempts: 3)
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`url:` is required and must not be blank. Extra keyword arguments are Bunny session options and override the global ones for that connection only; a `connection_name:` given here is used as-is instead of the generated label. The name `:default` is reserved. Publishing through a name that was never registered raises `Lepus::InvalidConnectionError`. See [producers.md](producers.md#named-connections).
|
|
43
|
+
|
|
31
44
|
## Application metadata
|
|
32
45
|
|
|
33
46
|
```ruby
|
|
@@ -72,7 +85,7 @@ Assign consumers to a named worker via their own `configure(process: { name: :hi
|
|
|
72
85
|
|
|
73
86
|
## Producer pool
|
|
74
87
|
|
|
75
|
-
Producers share a connection pool:
|
|
88
|
+
Producers share a connection pool per named connection (see [Named connections](#named-connections)); every pool uses these settings:
|
|
76
89
|
|
|
77
90
|
```ruby
|
|
78
91
|
config.producer do |p|
|
data/docs/producers.md
CHANGED
|
@@ -30,7 +30,8 @@ OrdersProducer.publish(
|
|
|
30
30
|
```ruby
|
|
31
31
|
configure(
|
|
32
32
|
exchange: { name: 'orders', type: :topic, durable: true },
|
|
33
|
-
publish: { persistent: true, mandatory: false }
|
|
33
|
+
publish: { persistent: true, mandatory: false },
|
|
34
|
+
connection: :default
|
|
34
35
|
)
|
|
35
36
|
```
|
|
36
37
|
|
|
@@ -38,6 +39,7 @@ configure(
|
|
|
38
39
|
|-----|---------|
|
|
39
40
|
| `exchange` | String (name only) or hash (`name`, `type`, `durable`, `auto_delete`). Auto-declared on first publish. |
|
|
40
41
|
| `publish` | Default publish options merged into every `publish` call: `persistent`, `mandatory`, `content_type`, `expiration`, etc. |
|
|
42
|
+
| `connection` | Named connection to publish through. Defaults to `:default` (`rabbitmq_url`). See [Named connections](#named-connections). |
|
|
41
43
|
|
|
42
44
|
## Publishing
|
|
43
45
|
|
|
@@ -119,7 +121,7 @@ OrdersProducer.order_created(order)
|
|
|
119
121
|
|
|
120
122
|
## Connection pooling
|
|
121
123
|
|
|
122
|
-
Producers share
|
|
124
|
+
Producers share one connection pool per named connection across the process:
|
|
123
125
|
|
|
124
126
|
```ruby
|
|
125
127
|
Lepus.configure do |config|
|
|
@@ -130,6 +132,32 @@ Lepus.configure do |config|
|
|
|
130
132
|
end
|
|
131
133
|
```
|
|
132
134
|
|
|
135
|
+
## Named connections
|
|
136
|
+
|
|
137
|
+
Register extra brokers in the configuration (see [configuration.md](configuration.md#named-connections)):
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
Lepus.configure do |config|
|
|
141
|
+
config.connection(:replica, url: ENV.fetch('REPLICA_RABBITMQ_URL'))
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then choose the connection per producer or per call. The per-call value wins, then the one in `configure`, then `:default`:
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
class AuditProducer < Lepus::Producer
|
|
149
|
+
configure(exchange: 'audit', connection: :replica)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
OrdersProducer.publish(payload, routing_key: 'order.created') # :default
|
|
153
|
+
OrdersProducer.publish(payload, routing_key: 'order.created', connection: :replica) # :replica
|
|
154
|
+
AuditProducer.publish(payload) # :replica
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`connection` is never sent to Bunny as a publish option. Each connection gets its own lazily created pool, so a broker that is down only affects the publishes routed to it. An unregistered name raises `Lepus::InvalidConnectionError`.
|
|
158
|
+
|
|
159
|
+
The low-level publisher takes the same option: `Lepus::Publisher.new('audit', connection: :replica)`.
|
|
160
|
+
|
|
133
161
|
## Enable / disable publishing
|
|
134
162
|
|
|
135
163
|
Useful when you want to disable side effects in tests or a specific environment.
|
data/docs/testing.md
CHANGED
|
@@ -89,6 +89,14 @@ end
|
|
|
89
89
|
|
|
90
90
|
`producer_messages(ProducerClass)` returns an array of hashes with `:payload`, `:routing_key`, `:delivery_info`, `:metadata`.
|
|
91
91
|
|
|
92
|
+
Each fake message also records the named connection it was published through:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
Lepus::Testing.exchange('orders').find_messages(connection: :replica)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The connection may be given as a symbol or a string. Publishing through a connection that was never registered with `config.connection` raises `Lepus::InvalidConnectionError`, as it does outside of fake mode.
|
|
99
|
+
|
|
92
100
|
## RSpec matchers
|
|
93
101
|
|
|
94
102
|
```ruby
|
data/lib/lepus/configuration.rb
CHANGED
|
@@ -8,6 +8,7 @@ module Lepus
|
|
|
8
8
|
DEFAULT_RECOVERY_INTERVAL = 5.0
|
|
9
9
|
DEFAULT_RECOVER_FROM_CONNECTION_CLOSE = true
|
|
10
10
|
DEFAULT_CONSUMERS_DIRECTORY = Pathname.new("app/consumers")
|
|
11
|
+
DEFAULT_CONNECTION = :default
|
|
11
12
|
|
|
12
13
|
# @return [String] the connection string for RabbitMQ.
|
|
13
14
|
attr_accessor :rabbitmq_url
|
|
@@ -93,17 +94,48 @@ module Lepus
|
|
|
93
94
|
Web::ManagementAPI.new(base_url: management_api_url)
|
|
94
95
|
end
|
|
95
96
|
|
|
97
|
+
# Registers a named RabbitMQ connection that producers can publish through.
|
|
98
|
+
# The :default connection is reserved and always uses {#rabbitmq_url}.
|
|
99
|
+
# @param name [Symbol, String] the connection name
|
|
100
|
+
# @param url [String] the connection string for RabbitMQ
|
|
101
|
+
# @param options [Hash] Bunny session options overriding the global ones
|
|
102
|
+
# @return [Hash] the connection settings
|
|
103
|
+
def connection(name, url:, **options)
|
|
104
|
+
name = name.to_sym
|
|
105
|
+
raise ArgumentError, "The #{DEFAULT_CONNECTION.inspect} connection is configured through rabbitmq_url" if name == DEFAULT_CONNECTION
|
|
106
|
+
raise ArgumentError, "The #{name.inspect} connection requires a url" if url.to_s.strip.empty?
|
|
107
|
+
|
|
108
|
+
connections[name] = options.merge(url: url)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @return [Hash{Symbol => Hash}] the named connections registered via {#connection}
|
|
112
|
+
def connections
|
|
113
|
+
@connections ||= {}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @param name [Symbol, String, nil] the connection name
|
|
117
|
+
# @return [Boolean] whether the connection is the default one or a registered named connection
|
|
118
|
+
def connection?(name)
|
|
119
|
+
name = (name || DEFAULT_CONNECTION).to_sym
|
|
120
|
+
name == DEFAULT_CONNECTION || connections.key?(name)
|
|
121
|
+
end
|
|
122
|
+
|
|
96
123
|
# @param suffix [String] the suffix to add to the connection name
|
|
124
|
+
# @param connection [Symbol, String] the named connection to open, :default uses {#rabbitmq_url}
|
|
97
125
|
# @return [Bunny::Session] the connection to RabbitMQ
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
126
|
+
# @raise [Lepus::InvalidConnectionError] when the connection name is not registered
|
|
127
|
+
def create_connection(suffix: nil, connection: DEFAULT_CONNECTION)
|
|
128
|
+
name = (connection || DEFAULT_CONNECTION).to_sym
|
|
129
|
+
url, options = connection_settings(name)
|
|
130
|
+
kwargs = connection_config.merge(options)
|
|
131
|
+
|
|
132
|
+
if connection_name && !options.key?(:connection_name)
|
|
133
|
+
label = [suffix, (name == DEFAULT_CONNECTION) ? nil : "(#{name})"].compact.join(" ")
|
|
134
|
+
kwargs[:connection_name] = "#{connection_name} #{label}" unless label.empty?
|
|
103
135
|
end
|
|
104
136
|
|
|
105
137
|
::Bunny
|
|
106
|
-
.new(
|
|
138
|
+
.new(url, **kwargs)
|
|
107
139
|
.tap { |conn| conn.start }
|
|
108
140
|
end
|
|
109
141
|
|
|
@@ -174,6 +206,15 @@ module Lepus
|
|
|
174
206
|
|
|
175
207
|
protected
|
|
176
208
|
|
|
209
|
+
def connection_settings(name)
|
|
210
|
+
return [rabbitmq_url, {}] if name == DEFAULT_CONNECTION
|
|
211
|
+
|
|
212
|
+
settings = connections.fetch(name) do
|
|
213
|
+
raise Lepus::InvalidConnectionError, "Unknown connection #{name.inspect}. Register it with Lepus.config.connection(#{name.inspect}, url: ...)"
|
|
214
|
+
end
|
|
215
|
+
[settings[:url], settings.reject { |key, _| key == :url }]
|
|
216
|
+
end
|
|
217
|
+
|
|
177
218
|
def connection_config
|
|
178
219
|
{
|
|
179
220
|
connection_name: connection_name,
|
|
@@ -9,12 +9,13 @@ module Lepus
|
|
|
9
9
|
DEFAULT_SIZE = 5
|
|
10
10
|
DEFAULT_TIMEOUT = 5.0
|
|
11
11
|
|
|
12
|
-
attr_reader :pool_size, :timeout, :conn_suffix
|
|
12
|
+
attr_reader :pool_size, :timeout, :conn_suffix, :conn_name
|
|
13
13
|
|
|
14
|
-
def initialize(size: DEFAULT_SIZE, timeout: DEFAULT_TIMEOUT, suffix: nil)
|
|
14
|
+
def initialize(size: DEFAULT_SIZE, timeout: DEFAULT_TIMEOUT, suffix: nil, connection: Lepus::Configuration::DEFAULT_CONNECTION)
|
|
15
15
|
@pool_size = size
|
|
16
16
|
@timeout = timeout
|
|
17
17
|
@conn_suffix = suffix
|
|
18
|
+
@conn_name = connection
|
|
18
19
|
@available = Concurrent::Array.new
|
|
19
20
|
@in_use = Concurrent::Array.new
|
|
20
21
|
@semaphore = Concurrent::Semaphore.new(pool_size)
|
|
@@ -62,7 +63,7 @@ module Lepus
|
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
# Create a new connection
|
|
65
|
-
connection = Lepus.config.create_connection(suffix: @conn_suffix)
|
|
66
|
+
connection = Lepus.config.create_connection(suffix: @conn_suffix, connection: @conn_name)
|
|
66
67
|
@mutex.with_write_lock do
|
|
67
68
|
@in_use << connection
|
|
68
69
|
end
|
data/lib/lepus/producer.rb
CHANGED
|
@@ -35,6 +35,7 @@ module Lepus
|
|
|
35
35
|
# @param [Hash] opts The options to configure the producer with.
|
|
36
36
|
# @option opts [String, Hash] :exchange The name of the exchange to publish to.
|
|
37
37
|
# @option opts [Hash] :publish Default publish options (persistent, mandatory, immediate).
|
|
38
|
+
# @option opts [Symbol] :connection The named connection to publish through. Defaults to :default.
|
|
38
39
|
# @yield [definition] Optional block to further configure the producer.
|
|
39
40
|
# @yieldparam [Lepus::Producers::Definition] definition The definition object.
|
|
40
41
|
# @return [Lepus::Producers::Definition] The configured producer definition.
|
|
@@ -42,6 +43,7 @@ module Lepus
|
|
|
42
43
|
raise ArgumentError, "Cannot configure an abstract class" if abstract_class?
|
|
43
44
|
|
|
44
45
|
@definition = Producers::Definition.new(opts)
|
|
46
|
+
@publishers = nil
|
|
45
47
|
yield(@definition) if block_given?
|
|
46
48
|
@definition
|
|
47
49
|
end
|
|
@@ -54,10 +56,13 @@ module Lepus
|
|
|
54
56
|
descendants.uniq
|
|
55
57
|
end
|
|
56
58
|
|
|
57
|
-
#
|
|
59
|
+
# Returns a publisher configured with this producer's settings, memoized per connection.
|
|
60
|
+
# @param connection [Symbol, String, nil] The named connection. Defaults to the configured one.
|
|
58
61
|
# @return [Lepus::Publisher] A publisher instance ready to send messages.
|
|
59
|
-
def publisher
|
|
60
|
-
|
|
62
|
+
def publisher(connection = nil)
|
|
63
|
+
name = (connection || definition.connection).to_sym
|
|
64
|
+
@publishers ||= {}
|
|
65
|
+
@publishers[name] ||= Publisher.new(definition.exchange_name, connection: name, **definition.exchange_options)
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
# Returns the middleware chain for this producer.
|
|
@@ -79,9 +84,11 @@ module Lepus
|
|
|
79
84
|
# Executes the middleware chain (global + per-producer) before publishing.
|
|
80
85
|
#
|
|
81
86
|
# @param payload [String, Hash] The message payload to publish.
|
|
87
|
+
# @param connection [Symbol, String, nil] The named connection to publish through,
|
|
88
|
+
# overriding the one set in {.configure}.
|
|
82
89
|
# @param options [Hash] Additional publish options (routing_key, headers, etc.).
|
|
83
90
|
# @return [void]
|
|
84
|
-
def publish(payload, **options)
|
|
91
|
+
def publish(payload, connection: nil, **options)
|
|
85
92
|
if definition.nil?
|
|
86
93
|
raise InvalidProducerConfigError, <<~ERROR
|
|
87
94
|
The #{name} producer is not configured.
|
|
@@ -99,7 +106,7 @@ module Lepus
|
|
|
99
106
|
)
|
|
100
107
|
|
|
101
108
|
combined_chain.execute(message) do |msg|
|
|
102
|
-
publisher.publish(msg.payload, **msg.to_publish_options)
|
|
109
|
+
publisher(connection).publish(msg.payload, **msg.to_publish_options)
|
|
103
110
|
end
|
|
104
111
|
end
|
|
105
112
|
|
|
@@ -142,8 +149,8 @@ module Lepus
|
|
|
142
149
|
|
|
143
150
|
attr_reader :definition
|
|
144
151
|
|
|
145
|
-
def publisher
|
|
146
|
-
|
|
152
|
+
def publisher(connection = nil)
|
|
153
|
+
self.class.publisher(connection)
|
|
147
154
|
end
|
|
148
155
|
|
|
149
156
|
def publish(message, **options)
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "forwardable"
|
|
4
|
-
|
|
5
3
|
module Lepus
|
|
6
4
|
module Producers
|
|
7
5
|
# Configuration class for producer settings
|
|
8
6
|
class Config
|
|
9
|
-
extend Forwardable
|
|
10
|
-
|
|
11
7
|
DEFAULT_POOL_SIZE = 1
|
|
12
8
|
DEFAULT_POOL_TIMEOUT = 5.0
|
|
13
9
|
|
|
14
10
|
attr_accessor :pool_size, :pool_timeout
|
|
15
11
|
|
|
16
|
-
def_delegator :connection_pool, :with_connection
|
|
17
|
-
|
|
18
12
|
def initialize
|
|
19
13
|
@pool_size = DEFAULT_POOL_SIZE
|
|
20
14
|
@pool_timeout = DEFAULT_POOL_TIMEOUT
|
|
15
|
+
@connection_pools = {}
|
|
16
|
+
@connection_pools_mutex = Mutex.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Checks out a connection from the pool of the given named connection.
|
|
20
|
+
# @param name [Symbol, String] the connection name, :default uses Lepus.config.rabbitmq_url
|
|
21
|
+
# @yieldparam connection [Bunny::Session]
|
|
22
|
+
# @raise [Lepus::InvalidConnectionError] when the connection name is not registered
|
|
23
|
+
def with_connection(name = Lepus::Configuration::DEFAULT_CONNECTION, &block)
|
|
24
|
+
connection_pool(name).with_connection(&block)
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
# Assign multiple attributes at once from a hash of options.
|
|
@@ -33,13 +37,22 @@ module Lepus
|
|
|
33
37
|
|
|
34
38
|
private
|
|
35
39
|
|
|
40
|
+
# @param name [Symbol, String] the connection name
|
|
36
41
|
# @return [Lepus::ConnectionPool] a connection pool instance configured for producers
|
|
37
|
-
def connection_pool
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
def connection_pool(name = Lepus::Configuration::DEFAULT_CONNECTION)
|
|
43
|
+
name = (name || Lepus::Configuration::DEFAULT_CONNECTION).to_sym
|
|
44
|
+
unless name == Lepus::Configuration::DEFAULT_CONNECTION || Lepus.config.connection?(name)
|
|
45
|
+
raise Lepus::InvalidConnectionError, "Unknown connection #{name.inspect}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@connection_pools_mutex.synchronize do
|
|
49
|
+
@connection_pools[name] ||= Lepus::ConnectionPool.new(
|
|
50
|
+
size: pool_size,
|
|
51
|
+
timeout: pool_timeout,
|
|
52
|
+
suffix: "producer",
|
|
53
|
+
connection: name
|
|
54
|
+
)
|
|
55
|
+
end
|
|
43
56
|
end
|
|
44
57
|
end
|
|
45
58
|
end
|
|
@@ -4,7 +4,7 @@ module Lepus
|
|
|
4
4
|
module Producers
|
|
5
5
|
# Definition class for producer-specific settings
|
|
6
6
|
class Definition
|
|
7
|
-
attr_reader :publish_options
|
|
7
|
+
attr_reader :publish_options, :connection
|
|
8
8
|
|
|
9
9
|
def initialize(options = {})
|
|
10
10
|
opts = Lepus::Primitive::Hash.new(options).deep_symbolize_keys
|
|
@@ -16,6 +16,8 @@ module Lepus
|
|
|
16
16
|
# Handle default publish options
|
|
17
17
|
@publish_options = Lepus::Publisher::DEFAULT_PUBLISH_OPTIONS.merge(opts.delete(:publish) || {})
|
|
18
18
|
|
|
19
|
+
@connection = (opts.delete(:connection) || Lepus::Configuration::DEFAULT_CONNECTION).to_sym
|
|
20
|
+
|
|
19
21
|
# Store any remaining options for future use
|
|
20
22
|
@options = opts
|
|
21
23
|
end
|
data/lib/lepus/publisher.rb
CHANGED
|
@@ -15,17 +15,22 @@ module Lepus
|
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
17
|
# @param exchange_name [String] The name of the exchange to publish messages to.
|
|
18
|
+
# @param connection [Symbol, String] The named connection to publish through.
|
|
18
19
|
# @param options [Hash] Additional options for the exchange (type, durable, auto_delete).
|
|
19
20
|
# @return [void]
|
|
20
|
-
def initialize(exchange_name, **options)
|
|
21
|
+
def initialize(exchange_name, connection: Lepus::Configuration::DEFAULT_CONNECTION, **options)
|
|
21
22
|
@exchange_name = exchange_name
|
|
23
|
+
@connection = (connection || Lepus::Configuration::DEFAULT_CONNECTION).to_sym
|
|
22
24
|
@exchange_options = DEFAULT_EXCHANGE_OPTIONS.merge(options)
|
|
23
25
|
end
|
|
24
26
|
|
|
27
|
+
# @return [Symbol] the named connection this publisher uses
|
|
28
|
+
attr_reader :connection
|
|
29
|
+
|
|
25
30
|
def publish(message, **options)
|
|
26
31
|
return unless Producers.exchange_enabled?(exchange_name)
|
|
27
32
|
|
|
28
|
-
Lepus.config.producer_config.with_connection do |connection|
|
|
33
|
+
Lepus.config.producer_config.with_connection(connection) do |connection|
|
|
29
34
|
connection.with_channel do |channel|
|
|
30
35
|
channel_publish(channel, message, **options)
|
|
31
36
|
end
|
|
@@ -45,6 +45,8 @@ module Lepus
|
|
|
45
45
|
message[:routing_key] == value
|
|
46
46
|
when :payload
|
|
47
47
|
message[:payload] == value
|
|
48
|
+
when :connection
|
|
49
|
+
message[:connection] == value&.to_sym
|
|
48
50
|
when :headers
|
|
49
51
|
message[:headers]&.any? { |k, v| value.any? { |vk, vv| k == vk && v == vv } }
|
|
50
52
|
else
|
data/lib/lepus/testing.rb
CHANGED
|
@@ -158,6 +158,10 @@ module Lepus
|
|
|
158
158
|
return unless Lepus::Producers.exchange_enabled?(exchange_name)
|
|
159
159
|
|
|
160
160
|
if Lepus::Testing.fake_publisher_enabled?
|
|
161
|
+
unless Lepus.config.connection?(connection)
|
|
162
|
+
raise Lepus::InvalidConnectionError, "Unknown connection #{connection.inspect}"
|
|
163
|
+
end
|
|
164
|
+
|
|
161
165
|
return fake_publish(message, **options)
|
|
162
166
|
end
|
|
163
167
|
|
|
@@ -186,6 +190,7 @@ module Lepus
|
|
|
186
190
|
|
|
187
191
|
fake_message = {
|
|
188
192
|
exchange: exchange_name,
|
|
193
|
+
connection: connection,
|
|
189
194
|
payload: message, # Store the original message, not the JSON string
|
|
190
195
|
routing_key: opts[:routing_key],
|
|
191
196
|
headers: opts[:headers],
|
data/lib/lepus/version.rb
CHANGED
data/lib/lepus.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lepus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marcos G. Zimmermann
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exec
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|