surfliner-metadata_consumer 0.1.0.pre.alpha.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fff0fe7a29854ecb3b75f91ed5aa1e5abdbf6fe7fc625b4b117a3e2c4e4805c
4
- data.tar.gz: 534536637b909d309f90095aaba4e9cb51a75d4ca92a78531971d3550ea42bfc
3
+ metadata.gz: c496d7587eb02bc3020be31fb8a9052e67e52aa08b97c3dbc81bb26d44f29fc3
4
+ data.tar.gz: 57d58bc7f428b049efc1e1f4db521970a8f43e389b966c20fb99156313c6c085
5
5
  SHA512:
6
- metadata.gz: 6e20f325aa14042b5ed7e950803d8a045834df543da1f5c4a8f30297645015d97add22a5de38e01d15a6ab74adb856777bba4fccfb609d50bd622c9fae1f51d5
7
- data.tar.gz: a69109802f8c408f077b2fc2d1c748c02a900eda042d6e40a4423ee3257b39d2dde892eecf9c77c690df06aa53d367136a8246f3d8bc69114d0e1278326b4531
6
+ metadata.gz: ebb4d7a8b61f8b03d4376454a526921d19e18eb94cca49029e8e75736ddee0ec61372a6bde72fafda21162eaa4f0ef655dc759f90150c309c8e20ec5404b450b
7
+ data.tar.gz: 43a75ff273881bf59ea4c20ae84e299b853b8c6779bc03e48e6fd42d6846a9268236aa034234ce8db6275ce600b255cac5eff23d722540496bc531347a589e7a
data/CHANGES.md CHANGED
@@ -1,3 +1,24 @@
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
+
10
+ # 0.1.0.pre.alpha.6 (2025-04-25)
11
+
12
+ - Update to Bunny 2.24
13
+ - Allow `Mq::Connection#connect` to take a block, in which case the method
14
+ yields the open connection, closing the connection and channel afterwards.
15
+ - Add an option `await_response_on_close` to `Mq::ConnectionConfig`, defaulting
16
+ to true, to indicate whether the RabbitMQ client should wait for a response
17
+ when closing a session, along with a corresponding environment variable
18
+ `RABBITMQ_AWAIT_ON_CLOSE`
19
+ - Allows passing additional options to `Mq:ConnectionConfig#initialize` and
20
+ `#from_env`, which will then be passed to `Bunny::Session#initialize`
21
+
1
22
  # 0.1.0.pre.alpha.5 (2025-03-25)
2
23
 
3
24
  In order to support using one connection (and one underlying `Bunny::Session`)
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- surfliner-metadata_consumer (0.1.0.pre.alpha.5)
5
- bunny (~> 2.23)
4
+ surfliner-metadata_consumer (0.1.0.pre.alpha.7)
5
+ bunny (~> 2.24)
6
6
  opentelemetry-exporter-otlp (~> 0.26.3)
7
7
  opentelemetry-instrumentation-all (~> 0.60.0)
8
8
  opentelemetry-sdk (~> 1.4.1)
@@ -37,26 +37,26 @@ GEM
37
37
  diff-lcs (1.6.1)
38
38
  docile (1.4.1)
39
39
  dotenv (2.8.1)
40
- faraday (2.12.2)
40
+ faraday (2.13.1)
41
41
  faraday-net_http (>= 2.0, < 3.5)
42
42
  json
43
43
  logger
44
44
  faraday-net_http (3.4.0)
45
45
  net-http (>= 0.5.0)
46
46
  github-markup (5.0.1)
47
- google-protobuf (3.25.6)
47
+ google-protobuf (3.25.7)
48
48
  googleapis-common-protos-types (1.19.0)
49
49
  google-protobuf (>= 3.18, < 5.a)
50
50
  hashdiff (1.1.2)
51
51
  io-console (0.8.0)
52
- irb (1.15.1)
52
+ irb (1.15.2)
53
53
  pp (>= 0.6.0)
54
54
  rdoc (>= 4.0.0)
55
55
  reline (>= 0.4.2)
56
- json (2.10.2)
56
+ json (2.11.3)
57
57
  language_server-protocol (3.17.0.4)
58
58
  lint_roller (1.1.0)
59
- logger (1.6.6)
59
+ logger (1.7.0)
60
60
  net-http (0.6.0)
61
61
  uri
62
62
  opentelemetry-api (1.5.0)
@@ -255,8 +255,8 @@ GEM
255
255
  opentelemetry-semantic_conventions
256
256
  opentelemetry-semantic_conventions (1.11.0)
257
257
  opentelemetry-api (~> 1.0)
258
- parallel (1.26.3)
259
- parser (3.3.7.2)
258
+ parallel (1.27.0)
259
+ parser (3.3.8.0)
260
260
  ast (~> 2.4.1)
261
261
  racc
262
262
  pp (0.6.2)
@@ -271,11 +271,11 @@ GEM
271
271
  rainbow (3.1.1)
272
272
  rake (13.2.1)
273
273
  rbtree (0.4.6)
274
- rdoc (6.13.0)
274
+ rdoc (6.13.1)
275
275
  psych (>= 4.0.0)
276
276
  redcarpet (3.6.1)
277
277
  regexp_parser (2.10.0)
278
- reline (0.6.0)
278
+ reline (0.6.1)
279
279
  io-console (~> 0.5)
280
280
  rexml (3.4.1)
281
281
  rsolr (2.6.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.73.2)
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)
@@ -302,15 +302,15 @@ GEM
302
302
  parser (>= 3.3.0.2)
303
303
  rainbow (>= 2.2.2, < 4.0)
304
304
  regexp_parser (>= 2.9.3, < 3.0)
305
- rubocop-ast (>= 1.38.0, < 2.0)
305
+ rubocop-ast (>= 1.44.0, < 2.0)
306
306
  ruby-progressbar (~> 1.7)
307
307
  unicode-display_width (>= 2.4.0, < 4.0)
308
- rubocop-ast (1.43.0)
308
+ rubocop-ast (1.44.1)
309
309
  parser (>= 3.3.7.2)
310
310
  prism (~> 1.4)
311
- rubocop-performance (1.24.0)
311
+ rubocop-performance (1.25.0)
312
312
  lint_roller (~> 1.1)
313
- rubocop (>= 1.72.1, < 2.0)
313
+ rubocop (>= 1.75.0, < 2.0)
314
314
  rubocop-ast (>= 1.38.0, < 2.0)
315
315
  ruby-progressbar (1.13.0)
316
316
  set (1.1.1)
@@ -326,19 +326,19 @@ GEM
326
326
  sorted_set (1.0.3)
327
327
  rbtree
328
328
  set (~> 1.0)
329
- standard (1.47.0)
329
+ standard (1.49.0)
330
330
  language_server-protocol (~> 3.17.0.2)
331
331
  lint_roller (~> 1.0)
332
- rubocop (~> 1.73.0)
332
+ rubocop (~> 1.75.2)
333
333
  standard-custom (~> 1.0.0)
334
- standard-performance (~> 1.7)
334
+ standard-performance (~> 1.8)
335
335
  standard-custom (1.0.2)
336
336
  lint_roller (~> 1.0)
337
337
  rubocop (~> 1.50)
338
- standard-performance (1.7.0)
338
+ standard-performance (1.8.0)
339
339
  lint_roller (~> 1.1)
340
- rubocop-performance (~> 1.24.0)
341
- stringio (3.1.6)
340
+ rubocop-performance (~> 1.25.0)
341
+ stringio (3.1.7)
342
342
  unicode-display_width (3.1.4)
343
343
  unicode-emoji (~> 4.0, >= 4.0.4)
344
344
  unicode-emoji (4.0.4)
@@ -370,4 +370,4 @@ DEPENDENCIES
370
370
  yard (~> 0.9.37)
371
371
 
372
372
  BUNDLED WITH
373
- 2.6.2
373
+ 2.6.7
data/README.md CHANGED
@@ -44,12 +44,13 @@ explicitly with a `ConnectionConfig` object, or implicitly, reading a default
44
44
  configuration with `ConnectionConfig#from_env`. `ConnectionConfig#from_env` expects
45
45
  the following environment variables:
46
46
 
47
- | Variable | Sample value | Description |
48
- |-----------------------------|--------------|------------------------------|
49
- | `RABBITMQ_HOST` | `rabbitmq` | Hostname of RabbitMQ server |
50
- | `RABBITMQ_NODE_PORT_NUMBER` | `5672` | Port name of RabbitMQ server |
51
- | `RABBITMQ_USERNAME` | `user` | RabbitMQ username |
52
- | `RABBITMQ_PASSWORD` | `bitnami` | RabbitMQ password |
47
+ | Variable | Sample value | Description |
48
+ |-----------------------------|--------------|-----------------------------------------------------------|
49
+ | `RABBITMQ_HOST` | `rabbitmq` | Hostname of RabbitMQ server |
50
+ | `RABBITMQ_NODE_PORT_NUMBER` | `5672` | Port name of RabbitMQ server |
51
+ | `RABBITMQ_USERNAME` | `user` | RabbitMQ username |
52
+ | `RABBITMQ_PASSWORD` | `bitnami` | RabbitMQ password |
53
+ | `RABBITMQ_AWAIT_ON_CLOSE` | `false` | Whether to wait on response when closing (default = true) |
53
54
 
54
55
  The `Mq::Connection#with_topic` and `Mq::Connection#topic_from` can either take an
55
56
  explicit `TopicConfig` object, or implicitly read a default configuration with
@@ -70,6 +71,13 @@ connection.with_topic(topic_config) do |topic|
70
71
  end
71
72
  ```
72
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
+
73
81
  Similarly, `Mq::Topic#bind_queue` can either take an explicit `QueueConfig`, or implicitly
74
82
  read a default with `QueConfig#from_env`. `QueueConfig#from_env` expects the following environment
75
83
  variables:
@@ -77,7 +85,6 @@ variables:
77
85
  | Variable | Sample value | Description |
78
86
  |---------------------------------|-------------------------------|----------------------|
79
87
  | `RABBITMQ_QUEUE` | `surfliner.metadata` | RabbitMQ queue name |
80
- | `RABBITMQ_PLATFORM_ROUTING_KEY` | `surfliner.metadata.daylight` | RabbitMQ routing key |
81
88
 
82
89
  And `QueueConfig#from_env` similarly accepts keyword options, which are forwarded to
83
90
  [`Bunny::Channel#queue`](https://api.rubybunny.info/Bunny/Channel.html#queue-instance_method):
@@ -2,6 +2,6 @@
2
2
  module Surfliner
3
3
  module MetadataConsumer
4
4
  # The gem version
5
- VERSION = "0.1.0.pre.alpha.5"
5
+ VERSION = "0.1.0.pre.alpha.7"
6
6
  end
7
7
  end
@@ -28,26 +28,22 @@ module Surfliner
28
28
  @config = not_nil!(config)
29
29
  end
30
30
 
31
- # Opens a connection.
32
- # @return [self]
31
+ # Opens this connection and creates a channel. If a block is
32
+ # given, yields the open connection, closing the connection and
33
+ # channel afterwards; otherwise, returns the open connection.
34
+ # @return [self] an open connection
35
+ # @yieldparam connection [self] an open connection
33
36
  # @raise [IOError] if already connected
34
37
  def connect
35
- raise IOError, "RabbitMQ session #{session} already open." if open?
38
+ init_connection
36
39
 
37
- logger.info("Rabbitmq message broker session url: #{config.redacted_url}")
38
- @session = Bunny.new(config.session_url, logger: logger)
39
- connect_on(session)
40
- @channel = session.create_channel
40
+ return self unless block_given?
41
41
 
42
- self
43
- rescue Bunny::TCPConnectionFailed => err
44
- # TODO: realistically, this only happens in session.start, where we're eating it
45
- logger.error("Connection to #{config.redacted_url} failed")
46
- raise err
47
- rescue Bunny::PossibleAuthenticationFailureError => err
48
- # TODO: realistically, this only happens in session.start, where we're eating it
49
- logger.error("Failed to authenticate to #{config.redacted_url}")
50
- raise err
42
+ begin
43
+ yield self
44
+ ensure
45
+ close
46
+ end
51
47
  end
52
48
 
53
49
  # Opens a session, yields a client for the specified topic, and closes the
@@ -55,11 +51,9 @@ module Surfliner
55
51
  # @param config [TopicConfig] topic configuration
56
52
  # @yield [MqTopic] A client for the topic
57
53
  def with_topic(config = TopicConfig.from_env)
58
- connect
59
-
60
- yield topic_from(config)
61
- ensure
62
- close
54
+ connect do |cxn|
55
+ yield cxn.topic_from(config)
56
+ end
63
57
  end
64
58
 
65
59
  # Returns a client for the specified topic. Note that this does _not_ open
@@ -76,13 +70,9 @@ module Surfliner
76
70
 
77
71
  # Closes the session.
78
72
  def close
79
- return unless channel
80
- return if channel.closed?
81
- logger.info("closing channel")
82
- channel.close
83
- ensure
84
73
  logger.info("closing session")
85
- session&.close
74
+ # Note: This will also close any open channels
75
+ session&.close(config.await_response_on_close)
86
76
  end
87
77
 
88
78
  # @return [true, false] True if the session is open, false otherwise
@@ -107,6 +97,24 @@ module Surfliner
107
97
 
108
98
  private
109
99
 
100
+ def init_connection
101
+ raise IOError, "RabbitMQ session #{session} already open." if open?
102
+
103
+ logger.info("Rabbitmq message broker session url: #{config.redacted_url}")
104
+ opts = {logger:}.merge(config.opts)
105
+ @session = Bunny.new(config.session_url, **opts)
106
+ connect_on(session)
107
+ @channel = session.create_channel
108
+ rescue Bunny::TCPConnectionFailed => err
109
+ # TODO: realistically, this only happens in session.start, where we're eating it
110
+ logger.error("Connection to #{config.redacted_url} failed")
111
+ raise err
112
+ rescue Bunny::PossibleAuthenticationFailureError => err
113
+ # TODO: realistically, this only happens in session.start, where we're eating it
114
+ logger.error("Failed to authenticate to #{config.redacted_url}")
115
+ raise err
116
+ end
117
+
110
118
  def connect_on(session, timeout = 120)
111
119
  timer = 0
112
120
  logger.info "Trying to open queue session with timeout=#{timeout}"
@@ -2,6 +2,9 @@ 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
6
+ FALSE_VALUES = ([""] + %w[0 off Off OFF f false False FALSE F n no No NO N]).freeze
7
+
5
8
  # @return [String] The RabbitMQ hostname
6
9
  attr_reader :host
7
10
 
@@ -14,36 +17,49 @@ module Surfliner
14
17
  # @return [String] The RabbitMQ passsword
15
18
  attr_reader :password
16
19
 
20
+ # @return [Boolean] whether the RabbitMQ client should wait for a response when closing the connection
21
+ attr_reader :await_response_on_close
22
+
23
+ # @return [Hash] Additional RabbitMQ connection options (see Bunny::Session#initialize)
24
+ attr_reader :opts
25
+
17
26
  # Initializes a new `MqConfig` object.
18
27
  # @param host [String] RabbitMQ hostname
19
28
  # @param port [String] RabbitMQ AMQP port
20
29
  # @param username [String] RabbitMQ username
21
30
  # @param password [String] RabbitMQ passsword
22
- def initialize(host:, port:, username:, password:)
31
+ # @param await_response_on_close [Boolean] whether the RabbitMQ client should wait for a response when closing the connection
32
+ # @param opts [Hash] additional RabbitMQ conection options (see Bunny::Session#initialize)
33
+ def initialize(host:, port:, username:, password:, await_response_on_close: true, **opts)
23
34
  @host = host
24
35
  @port = port
25
36
  @username = username
26
37
  @password = password
38
+ @await_response_on_close = parse_boolean(await_response_on_close)
39
+ @opts = opts
27
40
  end
28
41
 
29
42
  class << self
30
43
  # Reads RabbitMQ configuration from environment variables and
31
44
  # returns it as a new `ConnectionConfig` object.
32
45
  #
33
- # | Variable | Sample value | Description |
34
- # |-----------------------------|--------------|------------------------------|
35
- # | `RABBITMQ_HOST` | `rabbitmq` | Hostname of RabbitMQ server |
36
- # | `RABBITMQ_NODE_PORT_NUMBER` | `5672` | Port name of RabbitMQ server |
37
- # | `RABBITMQ_USERNAME` | `user` | RabbitMQ username |
38
- # | `RABBITMQ_PASSWORD` | `bitnami` | RabbitMQ password |
46
+ # | Variable | Sample value | Description |
47
+ # |-----------------------------|--------------|-----------------------------------------------------------|
48
+ # | `RABBITMQ_HOST` | `rabbitmq` | Hostname of RabbitMQ server |
49
+ # | `RABBITMQ_NODE_PORT_NUMBER` | `5672` | Port name of RabbitMQ server |
50
+ # | `RABBITMQ_USERNAME` | `user` | RabbitMQ username |
51
+ # | `RABBITMQ_PASSWORD` | `bitnami` | RabbitMQ password |
52
+ # | `RABBITMQ_AWAIT_ON_CLOSE` | `false` | Whether to wait on response when closing (default = true) |
39
53
  #
40
54
  # @return [ConnectionConfig] The configuration.
41
- def from_env
55
+ def from_env(**opts)
42
56
  ConnectionConfig.new(
43
57
  host: ENV.fetch("RABBITMQ_HOST"),
44
58
  port: ENV.fetch("RABBITMQ_NODE_PORT_NUMBER"),
45
59
  username: ENV.fetch("RABBITMQ_USERNAME"),
46
- password: ENV.fetch("RABBITMQ_PASSWORD")
60
+ password: ENV.fetch("RABBITMQ_PASSWORD"),
61
+ await_response_on_close: ENV["RABBITMQ_AWAIT_ON_CLOSE"] || true,
62
+ **opts
47
63
  )
48
64
  end
49
65
  end
@@ -57,6 +73,12 @@ module Surfliner
57
73
  def redacted_url
58
74
  @redacted_url ||= session_url.sub(password, "REDACTED")
59
75
  end
76
+
77
+ private
78
+
79
+ def parse_boolean(v)
80
+ !FALSE_VALUES.include?(v.to_s)
81
+ end
60
82
  end
61
83
  end
62
84
  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:, routing_key:, options: {})
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
@@ -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: QueueConfig.default_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
- # @return [Bunny::Queue] the queue
48
- def bind_queue(config = QueueConfig.from_env)
49
- channel.queue(config.name, config.options).tap do |q|
50
- q.bind(exchange, routing_key: config.routing_key)
51
- end
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,13 +1,13 @@
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.5
4
+ version: 0.1.0.pre.alpha.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Project Surfliner
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bunny
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '2.23'
18
+ version: '2.24'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '2.23'
25
+ version: '2.24'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: opentelemetry-exporter-otlp
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -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
@@ -320,7 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
321
  - !ruby/object:Gem::Version
321
322
  version: '0'
322
323
  requirements: []
323
- rubygems_version: 3.6.2
324
+ rubygems_version: 3.6.7
324
325
  specification_version: 4
325
326
  summary: Surfliner metadata consumer
326
327
  test_files: []