surfliner-metadata_consumer 0.1.0.pre.alpha.6 → 0.1.0.pre.alpha.7
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/CHANGES.md +9 -0
- data/Gemfile.lock +2 -2
- data/README.md +7 -1
- data/lib/surfliner/metadata_consumer/version.rb +1 -1
- data/lib/surfliner/mq/connection_config.rb +2 -1
- data/lib/surfliner/mq/queue_config.rb +1 -13
- data/lib/surfliner/mq/router.rb +78 -0
- data/lib/surfliner/mq/topic.rb +25 -6
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c496d7587eb02bc3020be31fb8a9052e67e52aa08b97c3dbc81bb26d44f29fc3
|
4
|
+
data.tar.gz: 57d58bc7f428b049efc1e1f4db521970a8f43e389b966c20fb99156313c6c085
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebb4d7a8b61f8b03d4376454a526921d19e18eb94cca49029e8e75736ddee0ec61372a6bde72fafda21162eaa4f0ef655dc759f90150c309c8e20ec5404b450b
|
7
|
+
data.tar.gz: 43a75ff273881bf59ea4c20ae84e299b853b8c6779bc03e48e6fd42d6846a9268236aa034234ce8db6275ce600b255cac5eff23d722540496bc531347a589e7a
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 0.1.0.pre.alpha.7 (2025-04-28)
|
2
|
+
|
3
|
+
- Fix issue where `RABBITMQ_AWAIT_ON_CLOSE` environment variable could
|
4
|
+
not be omitted.
|
5
|
+
- Remove `:routing_key` from `Mq::QueueConfig`, to allow using multiple
|
6
|
+
routing keys with the same queue.
|
7
|
+
- Add `Mq::Router` for routing messages from a single queue to multiple
|
8
|
+
handlers by routing key.
|
9
|
+
|
1
10
|
# 0.1.0.pre.alpha.6 (2025-04-25)
|
2
11
|
|
3
12
|
- Update to Bunny 2.24
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
surfliner-metadata_consumer (0.1.0.pre.alpha.
|
4
|
+
surfliner-metadata_consumer (0.1.0.pre.alpha.7)
|
5
5
|
bunny (~> 2.24)
|
6
6
|
opentelemetry-exporter-otlp (~> 0.26.3)
|
7
7
|
opentelemetry-instrumentation-all (~> 0.60.0)
|
@@ -294,7 +294,7 @@ GEM
|
|
294
294
|
diff-lcs (>= 1.2.0, < 2.0)
|
295
295
|
rspec-support (~> 3.13.0)
|
296
296
|
rspec-support (3.13.2)
|
297
|
-
rubocop (1.75.
|
297
|
+
rubocop (1.75.4)
|
298
298
|
json (~> 2.3)
|
299
299
|
language_server-protocol (~> 3.17.0.2)
|
300
300
|
lint_roller (~> 1.1.0)
|
data/README.md
CHANGED
@@ -71,6 +71,13 @@ connection.with_topic(topic_config) do |topic|
|
|
71
71
|
end
|
72
72
|
```
|
73
73
|
|
74
|
+
`TopicConfig#publish` can either accept an explicit routing key, or read a default value
|
75
|
+
from the environment:
|
76
|
+
|
77
|
+
| Variable | Sample value | Description |
|
78
|
+
|---------------------------------|-------------------------------|----------------------|
|
79
|
+
| `RABBITMQ_PLATFORM_ROUTING_KEY` | `surfliner.metadata.daylight` | RabbitMQ routing key |
|
80
|
+
|
74
81
|
Similarly, `Mq::Topic#bind_queue` can either take an explicit `QueueConfig`, or implicitly
|
75
82
|
read a default with `QueConfig#from_env`. `QueueConfig#from_env` expects the following environment
|
76
83
|
variables:
|
@@ -78,7 +85,6 @@ variables:
|
|
78
85
|
| Variable | Sample value | Description |
|
79
86
|
|---------------------------------|-------------------------------|----------------------|
|
80
87
|
| `RABBITMQ_QUEUE` | `surfliner.metadata` | RabbitMQ queue name |
|
81
|
-
| `RABBITMQ_PLATFORM_ROUTING_KEY` | `surfliner.metadata.daylight` | RabbitMQ routing key |
|
82
88
|
|
83
89
|
And `QueueConfig#from_env` similarly accepts keyword options, which are forwarded to
|
84
90
|
[`Bunny::Channel#queue`](https://api.rubybunny.info/Bunny/Channel.html#queue-instance_method):
|
@@ -2,6 +2,7 @@ module Surfliner
|
|
2
2
|
module Mq
|
3
3
|
# An object encapsulating RabbitMQ configuration.
|
4
4
|
class ConnectionConfig
|
5
|
+
# @return [Array<String>] values of RABBITMQ_AWAIT_ON_CLOSE interpreted as false
|
5
6
|
FALSE_VALUES = ([""] + %w[0 off Off OFF f false False FALSE F n no No NO N]).freeze
|
6
7
|
|
7
8
|
# @return [String] The RabbitMQ hostname
|
@@ -57,7 +58,7 @@ module Surfliner
|
|
57
58
|
port: ENV.fetch("RABBITMQ_NODE_PORT_NUMBER"),
|
58
59
|
username: ENV.fetch("RABBITMQ_USERNAME"),
|
59
60
|
password: ENV.fetch("RABBITMQ_PASSWORD"),
|
60
|
-
await_response_on_close: ENV
|
61
|
+
await_response_on_close: ENV["RABBITMQ_AWAIT_ON_CLOSE"] || true,
|
61
62
|
**opts
|
62
63
|
)
|
63
64
|
end
|
@@ -5,18 +5,13 @@ module Surfliner
|
|
5
5
|
# @return [String] The queue to listen to
|
6
6
|
attr_reader :name
|
7
7
|
|
8
|
-
# @return [String] platform routing key to listen to
|
9
|
-
attr_reader :routing_key
|
10
|
-
|
11
8
|
# @return [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
|
12
9
|
attr_reader :options
|
13
10
|
|
14
11
|
# @param name [String] queue exchange to listen to
|
15
|
-
# @param routing_key [String] platform routing key to listen to
|
16
12
|
# @param options [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
|
17
|
-
def initialize(name:,
|
13
|
+
def initialize(name:, options: {})
|
18
14
|
@name = name
|
19
|
-
@routing_key = routing_key
|
20
15
|
@options = options
|
21
16
|
end
|
22
17
|
|
@@ -27,22 +22,15 @@ module Surfliner
|
|
27
22
|
# | Variable | Sample value | Description |
|
28
23
|
# |---------------------------------|-------------------------------|----------------------|
|
29
24
|
# | `RABBITMQ_QUEUE` | `surfliner.metadata` | RabbitMQ queue name |
|
30
|
-
# | `RABBITMQ_PLATFORM_ROUTING_KEY` | `surfliner.metadata.daylight` | RabbitMQ routing key |
|
31
25
|
#
|
32
26
|
# @param options [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
|
33
27
|
# @return [QueueConfig] The configuration.
|
34
28
|
def from_env(**options)
|
35
29
|
QueueConfig.new(
|
36
30
|
name: ENV.fetch("RABBITMQ_QUEUE"),
|
37
|
-
routing_key: default_routing_key,
|
38
31
|
options:
|
39
32
|
)
|
40
33
|
end
|
41
|
-
|
42
|
-
# @return [String] The default routing key from `ENV["RABBITMQ_PLATFORM_ROUTING_KEY"]`
|
43
|
-
def default_routing_key
|
44
|
-
ENV.fetch("RABBITMQ_PLATFORM_ROUTING_KEY")
|
45
|
-
end
|
46
34
|
end
|
47
35
|
end
|
48
36
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Surfliner
|
2
|
+
module Mq
|
3
|
+
# Queue subscriber that routes messages by routing key to multiple handlers
|
4
|
+
class Router
|
5
|
+
# @return [Topic] the topic
|
6
|
+
attr_reader :topic
|
7
|
+
|
8
|
+
# @return [Bunny::Queue] the queue
|
9
|
+
attr_reader :queue
|
10
|
+
|
11
|
+
# @return [Bunny::Consumer] the consumer (used to unsubscribe)
|
12
|
+
attr_reader :consumer
|
13
|
+
|
14
|
+
# Initializes a new Router and subscribes it to the specified queue
|
15
|
+
# on the specified topic.
|
16
|
+
#
|
17
|
+
# @param topic [Mq::Topic] The topic to listen on
|
18
|
+
# @param queue_config [Mq::QueueConfig] The queue to subscribe to
|
19
|
+
def initialize(topic, queue_config: QueueConfig.from_env)
|
20
|
+
@topic = topic
|
21
|
+
@queue = topic.queue(queue_config)
|
22
|
+
@consumer = queue.subscribe(&method(:on_delivery))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds a handler for the specified routing key.
|
26
|
+
# Handlers will receive only messages with the specified routing key.
|
27
|
+
# Multiple handler blocks can be added to the same queue and/or routing key.
|
28
|
+
#
|
29
|
+
# @param routing_key [String] the routing key to filter messages by
|
30
|
+
# @yieldparam payload_json [String] each payload
|
31
|
+
def add_handler(routing_key, &block)
|
32
|
+
raise "Can't add handlers after router shutdown" if consumer.nil?
|
33
|
+
|
34
|
+
log("adding handler #{block}")
|
35
|
+
handlers = handlers_for(routing_key)
|
36
|
+
queue.bind(topic.exchange, routing_key:) if handlers.empty?
|
37
|
+
handlers << block
|
38
|
+
end
|
39
|
+
|
40
|
+
# Removes all handlers and unsubscribes from the queue.
|
41
|
+
def shutdown
|
42
|
+
log("shutting down")
|
43
|
+
handlers_by_routing_key.clear
|
44
|
+
consumer.cancel
|
45
|
+
@consumer = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Receives messages and routes them to the appropriate handler
|
51
|
+
#
|
52
|
+
# @param delivery_info [Bunny::DeliveryInfo] the delivery info
|
53
|
+
# @param _metadata [Bunny::MessageProperties] the message properties
|
54
|
+
# @param payload_json [String] the payload as a string
|
55
|
+
def on_delivery(delivery_info, _metadata, payload_json)
|
56
|
+
routing_key = delivery_info.routing_key
|
57
|
+
handlers_for(routing_key).each do |handler|
|
58
|
+
log("delivering #{payload_json} to handler #{handler} for #{routing_key}")
|
59
|
+
handler.call(payload_json)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Hash{String => Array<Proc>}] all handlers by routing key
|
64
|
+
def handlers_by_routing_key
|
65
|
+
@handlers_by_routing_key ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Array<Proc>] the handlers for the specified key, if any
|
69
|
+
def handlers_for(routing_key)
|
70
|
+
(handlers_by_routing_key[routing_key] ||= [])
|
71
|
+
end
|
72
|
+
|
73
|
+
def log(msg)
|
74
|
+
topic.logger.debug("#{self.class}(#{topic.name}, #{queue.name}): #{msg}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/surfliner/mq/topic.rb
CHANGED
@@ -38,17 +38,36 @@ module Surfliner
|
|
38
38
|
# @param payload [String] the payload to publish
|
39
39
|
# @param routing_key [String] platform routing key to publish to
|
40
40
|
# @return [Bunny::Exchange] see #exchange
|
41
|
-
def publish(payload, routing_key:
|
41
|
+
def publish(payload, routing_key: default_routing_key)
|
42
42
|
logger.info "Publishing to #{routing_key} with payload: #{payload}"
|
43
43
|
exchange.publish(payload, routing_key:)
|
44
44
|
end
|
45
45
|
|
46
|
+
# Creates or looks up the specified queue and binds it to receive
|
47
|
+
# messages with the specified routing key.
|
46
48
|
# @param config [QueueConfig] queue configuration
|
47
|
-
# @
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
# @param routing_key [String] platform routing key to bind on
|
50
|
+
# @return [Bunny::Queue] the queue
|
51
|
+
def bind_queue(config = QueueConfig.from_env, routing_key: default_routing_key)
|
52
|
+
queue(config).tap { |q| q.bind(exchange, routing_key:) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates or looks up the specified queue.
|
56
|
+
# @param config [QueueConfig] queue configuration
|
57
|
+
# @return [Bunny::Queue] the queue
|
58
|
+
def queue(config)
|
59
|
+
channel.queue(config.name, config.options)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the default (environment-variable-based) routing key
|
63
|
+
#
|
64
|
+
# | Variable | Sample value | Description |
|
65
|
+
# |---------------------------------|-------------------------------|----------------------|
|
66
|
+
# | `RABBITMQ_PLATFORM_ROUTING_KEY` | `surfliner.metadata.daylight` | RabbitMQ routing key |
|
67
|
+
#
|
68
|
+
# @return [String, nil] the configured default routing key
|
69
|
+
def default_routing_key
|
70
|
+
ENV.fetch("RABBITMQ_PLATFORM_ROUTING_KEY")
|
52
71
|
end
|
53
72
|
|
54
73
|
class << self
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surfliner-metadata_consumer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.pre.alpha.
|
4
|
+
version: 0.1.0.pre.alpha.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Project Surfliner
|
@@ -295,6 +295,7 @@ files:
|
|
295
295
|
- lib/surfliner/mq/connection.rb
|
296
296
|
- lib/surfliner/mq/connection_config.rb
|
297
297
|
- lib/surfliner/mq/queue_config.rb
|
298
|
+
- lib/surfliner/mq/router.rb
|
298
299
|
- lib/surfliner/mq/topic.rb
|
299
300
|
- lib/surfliner/mq/topic_config.rb
|
300
301
|
- lib/surfliner/util.rb
|