jetstream_bridge 4.1.0 → 4.3.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 +86 -0
- data/README.md +25 -1426
- data/docs/GETTING_STARTED.md +97 -0
- data/docs/PRODUCTION.md +503 -0
- data/docs/TESTING.md +414 -0
- data/lib/jetstream_bridge/consumer/consumer.rb +16 -4
- data/lib/jetstream_bridge/consumer/inbox/inbox_processor.rb +17 -3
- data/lib/jetstream_bridge/consumer/inbox/inbox_repository.rb +19 -7
- data/lib/jetstream_bridge/consumer/message_processor.rb +88 -52
- data/lib/jetstream_bridge/consumer/subscription_manager.rb +24 -15
- data/lib/jetstream_bridge/core/bridge_helpers.rb +90 -0
- data/lib/jetstream_bridge/core/connection.rb +21 -5
- data/lib/jetstream_bridge/core.rb +8 -0
- data/lib/jetstream_bridge/models/inbox_event.rb +2 -2
- data/lib/jetstream_bridge/models/outbox_event.rb +2 -2
- data/lib/jetstream_bridge/publisher/publisher.rb +8 -6
- data/lib/jetstream_bridge/rails/integration.rb +148 -0
- data/lib/jetstream_bridge/rails/railtie.rb +53 -0
- data/lib/jetstream_bridge/rails.rb +5 -0
- data/lib/jetstream_bridge/tasks/install.rake +1 -1
- data/lib/jetstream_bridge/test_helpers/fixtures.rb +41 -0
- data/lib/jetstream_bridge/test_helpers/integration_helpers.rb +77 -0
- data/lib/jetstream_bridge/test_helpers/matchers.rb +98 -0
- data/lib/jetstream_bridge/test_helpers.rb +4 -259
- data/lib/jetstream_bridge/topology/stream.rb +1 -1
- data/lib/jetstream_bridge/version.rb +1 -1
- data/lib/jetstream_bridge.rb +56 -97
- metadata +21 -8
- data/lib/jetstream_bridge/railtie.rb +0 -91
data/lib/jetstream_bridge.rb
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'jetstream_bridge/version'
|
|
4
|
-
require_relative 'jetstream_bridge/core
|
|
5
|
-
require_relative 'jetstream_bridge/core/duration'
|
|
6
|
-
require_relative 'jetstream_bridge/core/logging'
|
|
7
|
-
require_relative 'jetstream_bridge/core/connection'
|
|
4
|
+
require_relative 'jetstream_bridge/core'
|
|
8
5
|
require_relative 'jetstream_bridge/publisher/publisher'
|
|
9
6
|
require_relative 'jetstream_bridge/publisher/batch_publisher'
|
|
10
7
|
require_relative 'jetstream_bridge/consumer/consumer'
|
|
@@ -12,8 +9,8 @@ require_relative 'jetstream_bridge/consumer/middleware'
|
|
|
12
9
|
require_relative 'jetstream_bridge/models/publish_result'
|
|
13
10
|
require_relative 'jetstream_bridge/models/event'
|
|
14
11
|
|
|
15
|
-
#
|
|
16
|
-
require_relative 'jetstream_bridge/
|
|
12
|
+
# Rails-specific entry point (lifecycle helpers + Railtie)
|
|
13
|
+
require_relative 'jetstream_bridge/rails' if defined?(Rails::Railtie)
|
|
17
14
|
|
|
18
15
|
# Load gem-provided models from lib/
|
|
19
16
|
require_relative 'jetstream_bridge/models/inbox_event'
|
|
@@ -34,7 +31,7 @@ require_relative 'jetstream_bridge/models/outbox_event'
|
|
|
34
31
|
# - Graceful startup/shutdown lifecycle management
|
|
35
32
|
#
|
|
36
33
|
# @example Quick start
|
|
37
|
-
# # Configure
|
|
34
|
+
# # Configure
|
|
38
35
|
# JetstreamBridge.configure do |config|
|
|
39
36
|
# config.nats_urls = "nats://localhost:4222"
|
|
40
37
|
# config.env = "development"
|
|
@@ -44,6 +41,9 @@ require_relative 'jetstream_bridge/models/outbox_event'
|
|
|
44
41
|
# config.use_inbox = true
|
|
45
42
|
# end
|
|
46
43
|
#
|
|
44
|
+
# # Explicitly start connection (or use Rails railtie for automatic startup)
|
|
45
|
+
# JetstreamBridge.startup!
|
|
46
|
+
#
|
|
47
47
|
# # Publish events
|
|
48
48
|
# JetstreamBridge.publish(
|
|
49
49
|
# event_type: "user.created",
|
|
@@ -66,17 +66,17 @@ require_relative 'jetstream_bridge/models/outbox_event'
|
|
|
66
66
|
#
|
|
67
67
|
module JetstreamBridge
|
|
68
68
|
class << self
|
|
69
|
+
include Core::BridgeHelpers
|
|
70
|
+
|
|
69
71
|
def config
|
|
70
72
|
@config ||= Config.new
|
|
71
73
|
end
|
|
72
74
|
|
|
73
|
-
# Configure JetStream Bridge settings
|
|
74
|
-
#
|
|
75
|
-
# This method sets configuration and immediately establishes a connection
|
|
76
|
-
# to NATS, providing fail-fast behavior during application startup.
|
|
77
|
-
# If NATS is unavailable, the application will fail to start.
|
|
75
|
+
# Configure JetStream Bridge settings
|
|
78
76
|
#
|
|
79
|
-
#
|
|
77
|
+
# This method sets configuration WITHOUT automatically establishing a connection.
|
|
78
|
+
# Connection must be established explicitly via startup! or will be established
|
|
79
|
+
# automatically on first use (publish/subscribe) or via Rails railtie initialization.
|
|
80
80
|
#
|
|
81
81
|
# @example Basic configuration
|
|
82
82
|
# JetstreamBridge.configure do |config|
|
|
@@ -84,38 +84,29 @@ module JetstreamBridge
|
|
|
84
84
|
# config.app_name = "my_app"
|
|
85
85
|
# config.destination_app = "worker"
|
|
86
86
|
# end
|
|
87
|
+
# JetstreamBridge.startup! # Explicitly start connection
|
|
87
88
|
#
|
|
88
89
|
# @example With hash overrides
|
|
89
90
|
# JetstreamBridge.configure(env: 'production', app_name: 'my_app')
|
|
90
91
|
#
|
|
91
|
-
# @example Lazy connection (defer until first use)
|
|
92
|
-
# JetstreamBridge.configure do |config|
|
|
93
|
-
# config.nats_urls = "nats://localhost:4222"
|
|
94
|
-
# config.lazy_connect = true
|
|
95
|
-
# end
|
|
96
|
-
#
|
|
97
92
|
# @param overrides [Hash] Configuration key-value pairs to set
|
|
98
93
|
# @yield [Config] Configuration object for block-based configuration
|
|
99
94
|
# @return [Config] The configured instance
|
|
100
|
-
# @raise [ConnectionError] If connection to NATS fails (unless lazy_connect is true)
|
|
101
95
|
def configure(overrides = {}, **extra_overrides)
|
|
102
96
|
# Merge extra keyword arguments into overrides hash
|
|
103
97
|
all_overrides = overrides.nil? ? extra_overrides : overrides.merge(extra_overrides)
|
|
104
98
|
|
|
105
99
|
cfg = config
|
|
106
|
-
all_overrides.each { |k, v|
|
|
100
|
+
all_overrides.each { |k, v| assign_config_option!(cfg, k, v) } unless all_overrides.empty?
|
|
107
101
|
yield(cfg) if block_given?
|
|
108
102
|
|
|
109
|
-
# Establish connection immediately for fail-fast behavior (unless lazy_connect is true)
|
|
110
|
-
startup! unless cfg.lazy_connect
|
|
111
|
-
|
|
112
103
|
cfg
|
|
113
104
|
end
|
|
114
105
|
|
|
115
|
-
# Configure with a preset
|
|
106
|
+
# Configure with a preset
|
|
116
107
|
#
|
|
117
|
-
# This method applies a configuration preset
|
|
118
|
-
#
|
|
108
|
+
# This method applies a configuration preset. Connection must be
|
|
109
|
+
# established separately via startup! or via Rails railtie.
|
|
119
110
|
#
|
|
120
111
|
# @example
|
|
121
112
|
# JetstreamBridge.configure_for(:production) do |config|
|
|
@@ -123,11 +114,11 @@ module JetstreamBridge
|
|
|
123
114
|
# config.app_name = "my_app"
|
|
124
115
|
# config.destination_app = "worker"
|
|
125
116
|
# end
|
|
117
|
+
# JetstreamBridge.startup! # Explicitly start connection
|
|
126
118
|
#
|
|
127
119
|
# @param preset [Symbol] Preset name (:development, :test, :production, etc.)
|
|
128
120
|
# @yield [Config] Configuration object
|
|
129
121
|
# @return [Config] Configured instance
|
|
130
|
-
# @raise [ConnectionError] If connection to NATS fails
|
|
131
122
|
def configure_for(preset)
|
|
132
123
|
configure do |cfg|
|
|
133
124
|
cfg.apply_preset(preset)
|
|
@@ -142,18 +133,37 @@ module JetstreamBridge
|
|
|
142
133
|
|
|
143
134
|
# Initialize the JetStream Bridge connection and topology
|
|
144
135
|
#
|
|
145
|
-
# This method
|
|
146
|
-
# explicitly if needed. It's idempotent and safe to call multiple times.
|
|
136
|
+
# This method can be called explicitly if needed. It's idempotent and safe to call multiple times.
|
|
147
137
|
#
|
|
148
138
|
# @return [void]
|
|
149
139
|
def startup!
|
|
150
140
|
return if @connection_initialized
|
|
151
141
|
|
|
152
|
-
|
|
142
|
+
connect_and_ensure_stream!
|
|
153
143
|
@connection_initialized = true
|
|
154
144
|
Logging.info('JetStream Bridge started successfully', tag: 'JetstreamBridge')
|
|
155
145
|
end
|
|
156
146
|
|
|
147
|
+
# Reconnect to NATS
|
|
148
|
+
#
|
|
149
|
+
# Closes existing connection and establishes a new one. Useful for:
|
|
150
|
+
# - Forking web servers (Puma, Unicorn) after worker boot
|
|
151
|
+
# - Recovering from connection issues
|
|
152
|
+
# - Configuration changes that require reconnection
|
|
153
|
+
#
|
|
154
|
+
# @example In Puma configuration (config/puma.rb)
|
|
155
|
+
# on_worker_boot do
|
|
156
|
+
# JetstreamBridge.reconnect! if defined?(JetstreamBridge)
|
|
157
|
+
# end
|
|
158
|
+
#
|
|
159
|
+
# @return [void]
|
|
160
|
+
# @raise [ConnectionError] If unable to reconnect to NATS
|
|
161
|
+
def reconnect!
|
|
162
|
+
Logging.info('Reconnecting to NATS...', tag: 'JetstreamBridge')
|
|
163
|
+
shutdown! if @connection_initialized
|
|
164
|
+
startup!
|
|
165
|
+
end
|
|
166
|
+
|
|
157
167
|
# Gracefully shutdown the JetStream Bridge connection
|
|
158
168
|
#
|
|
159
169
|
# Closes the NATS connection and cleans up resources. Should be called
|
|
@@ -189,9 +199,16 @@ module JetstreamBridge
|
|
|
189
199
|
# Establishes a connection and ensures stream topology.
|
|
190
200
|
#
|
|
191
201
|
# @return [Object] JetStream context
|
|
192
|
-
def
|
|
202
|
+
def connect_and_ensure_stream!
|
|
193
203
|
Connection.connect!
|
|
194
|
-
Connection.jetstream
|
|
204
|
+
jts = Connection.jetstream
|
|
205
|
+
Topology.ensure!(jts)
|
|
206
|
+
jts
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Backwards-compatible alias for the previous method name
|
|
210
|
+
def ensure_topology!
|
|
211
|
+
connect_and_ensure_stream!
|
|
195
212
|
end
|
|
196
213
|
|
|
197
214
|
# Active health check for monitoring and readiness probes
|
|
@@ -283,6 +300,8 @@ module JetstreamBridge
|
|
|
283
300
|
|
|
284
301
|
# Convenience method to publish events
|
|
285
302
|
#
|
|
303
|
+
# Automatically establishes connection on first use if not already connected.
|
|
304
|
+
#
|
|
286
305
|
# Supports three usage patterns:
|
|
287
306
|
#
|
|
288
307
|
# 1. Structured parameters (recommended):
|
|
@@ -310,6 +329,7 @@ module JetstreamBridge
|
|
|
310
329
|
# logger.error("Publish failed: #{result.error}")
|
|
311
330
|
# end
|
|
312
331
|
def publish(event_or_hash = nil, resource_type: nil, event_type: nil, payload: nil, subject: nil, **)
|
|
332
|
+
connect_if_needed!
|
|
313
333
|
publisher = Publisher.new
|
|
314
334
|
publisher.publish(event_or_hash, resource_type: resource_type, event_type: event_type, payload: payload,
|
|
315
335
|
subject: subject, **)
|
|
@@ -354,6 +374,8 @@ module JetstreamBridge
|
|
|
354
374
|
|
|
355
375
|
# Convenience method to start consuming messages
|
|
356
376
|
#
|
|
377
|
+
# Automatically establishes connection on first use if not already connected.
|
|
378
|
+
#
|
|
357
379
|
# Supports two usage patterns:
|
|
358
380
|
#
|
|
359
381
|
# 1. With a block (recommended):
|
|
@@ -380,6 +402,7 @@ module JetstreamBridge
|
|
|
380
402
|
# @yield [event] Yields Models::Event object to block
|
|
381
403
|
# @return [Consumer, Thread] Consumer instance or Thread if run: true
|
|
382
404
|
def subscribe(handler = nil, run: false, durable_name: nil, batch_size: nil, &block)
|
|
405
|
+
connect_if_needed!
|
|
383
406
|
handler ||= block
|
|
384
407
|
raise ArgumentError, 'Handler or block required' unless handler
|
|
385
408
|
|
|
@@ -393,69 +416,5 @@ module JetstreamBridge
|
|
|
393
416
|
consumer
|
|
394
417
|
end
|
|
395
418
|
end
|
|
396
|
-
|
|
397
|
-
private
|
|
398
|
-
|
|
399
|
-
# Enforce rate limit on uncached health checks to prevent abuse
|
|
400
|
-
# Max 1 uncached request per 5 seconds per process
|
|
401
|
-
def enforce_health_check_rate_limit!
|
|
402
|
-
@health_check_mutex ||= Mutex.new
|
|
403
|
-
@health_check_mutex.synchronize do
|
|
404
|
-
now = Time.now
|
|
405
|
-
if @last_uncached_health_check
|
|
406
|
-
time_since = now - @last_uncached_health_check
|
|
407
|
-
if time_since < 5
|
|
408
|
-
raise HealthCheckFailedError,
|
|
409
|
-
"Health check rate limit exceeded. Please wait #{(5 - time_since).ceil} second(s)"
|
|
410
|
-
end
|
|
411
|
-
end
|
|
412
|
-
@last_uncached_health_check = now
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
def fetch_stream_info
|
|
417
|
-
jts = Connection.jetstream
|
|
418
|
-
info = jts.stream_info(config.stream_name)
|
|
419
|
-
|
|
420
|
-
# Handle both object-style and hash-style access for compatibility
|
|
421
|
-
config_data = info.config
|
|
422
|
-
state_data = info.state
|
|
423
|
-
subjects = config_data.respond_to?(:subjects) ? config_data.subjects : config_data[:subjects]
|
|
424
|
-
messages = state_data.respond_to?(:messages) ? state_data.messages : state_data[:messages]
|
|
425
|
-
|
|
426
|
-
{
|
|
427
|
-
exists: true,
|
|
428
|
-
name: config.stream_name,
|
|
429
|
-
subjects: subjects,
|
|
430
|
-
messages: messages
|
|
431
|
-
}
|
|
432
|
-
rescue StandardError => e
|
|
433
|
-
{
|
|
434
|
-
exists: false,
|
|
435
|
-
name: config.stream_name,
|
|
436
|
-
error: "#{e.class}: #{e.message}"
|
|
437
|
-
}
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
def measure_nats_rtt
|
|
441
|
-
# Measure round-trip time using NATS RTT method
|
|
442
|
-
nc = Connection.nc
|
|
443
|
-
start = Time.now
|
|
444
|
-
nc.rtt
|
|
445
|
-
((Time.now - start) * 1000).round(2)
|
|
446
|
-
rescue StandardError => e
|
|
447
|
-
Logging.warn(
|
|
448
|
-
"Failed to measure NATS RTT: #{e.class} #{e.message}",
|
|
449
|
-
tag: 'JetstreamBridge'
|
|
450
|
-
)
|
|
451
|
-
nil
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
def assign!(cfg, key, val)
|
|
455
|
-
setter = :"#{key}="
|
|
456
|
-
raise ArgumentError, "Unknown configuration option: #{key}" unless cfg.respond_to?(setter)
|
|
457
|
-
|
|
458
|
-
cfg.public_send(setter, val)
|
|
459
|
-
end
|
|
460
419
|
end
|
|
461
420
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jetstream_bridge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Attara
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -105,19 +105,25 @@ dependencies:
|
|
|
105
105
|
- !ruby/object:Gem::Version
|
|
106
106
|
version: '4.0'
|
|
107
107
|
description: |-
|
|
108
|
-
|
|
109
|
-
overlap guards, DLQ routing, retries/backoff, and optional
|
|
110
|
-
Includes health checks, auto-reconnection, graceful shutdown,
|
|
111
|
-
helpers
|
|
108
|
+
Production-ready publishers/consumers for NATS JetStream with environment-scoped
|
|
109
|
+
subjects, overlap guards, DLQ routing, retries/backoff, and optional inbox/outbox
|
|
110
|
+
patterns. Includes health checks, auto-reconnection, graceful shutdown, topology
|
|
111
|
+
setup helpers, and Rails generators.
|
|
112
112
|
email:
|
|
113
113
|
- mpyebattara@gmail.com
|
|
114
114
|
executables: []
|
|
115
115
|
extensions: []
|
|
116
|
-
extra_rdoc_files:
|
|
116
|
+
extra_rdoc_files:
|
|
117
|
+
- README.md
|
|
118
|
+
- CHANGELOG.md
|
|
119
|
+
- docs/GETTING_STARTED.md
|
|
117
120
|
files:
|
|
118
121
|
- CHANGELOG.md
|
|
119
122
|
- LICENSE
|
|
120
123
|
- README.md
|
|
124
|
+
- docs/GETTING_STARTED.md
|
|
125
|
+
- docs/PRODUCTION.md
|
|
126
|
+
- docs/TESTING.md
|
|
121
127
|
- lib/generators/jetstream_bridge/health_check/health_check_generator.rb
|
|
122
128
|
- lib/generators/jetstream_bridge/health_check/templates/health_controller.rb
|
|
123
129
|
- lib/generators/jetstream_bridge/initializer/initializer_generator.rb
|
|
@@ -135,6 +141,8 @@ files:
|
|
|
135
141
|
- lib/jetstream_bridge/consumer/message_processor.rb
|
|
136
142
|
- lib/jetstream_bridge/consumer/middleware.rb
|
|
137
143
|
- lib/jetstream_bridge/consumer/subscription_manager.rb
|
|
144
|
+
- lib/jetstream_bridge/core.rb
|
|
145
|
+
- lib/jetstream_bridge/core/bridge_helpers.rb
|
|
138
146
|
- lib/jetstream_bridge/core/config.rb
|
|
139
147
|
- lib/jetstream_bridge/core/config_preset.rb
|
|
140
148
|
- lib/jetstream_bridge/core/connection.rb
|
|
@@ -155,9 +163,14 @@ files:
|
|
|
155
163
|
- lib/jetstream_bridge/publisher/batch_publisher.rb
|
|
156
164
|
- lib/jetstream_bridge/publisher/outbox_repository.rb
|
|
157
165
|
- lib/jetstream_bridge/publisher/publisher.rb
|
|
158
|
-
- lib/jetstream_bridge/
|
|
166
|
+
- lib/jetstream_bridge/rails.rb
|
|
167
|
+
- lib/jetstream_bridge/rails/integration.rb
|
|
168
|
+
- lib/jetstream_bridge/rails/railtie.rb
|
|
159
169
|
- lib/jetstream_bridge/tasks/install.rake
|
|
160
170
|
- lib/jetstream_bridge/test_helpers.rb
|
|
171
|
+
- lib/jetstream_bridge/test_helpers/fixtures.rb
|
|
172
|
+
- lib/jetstream_bridge/test_helpers/integration_helpers.rb
|
|
173
|
+
- lib/jetstream_bridge/test_helpers/matchers.rb
|
|
161
174
|
- lib/jetstream_bridge/test_helpers/mock_nats.rb
|
|
162
175
|
- lib/jetstream_bridge/topology/overlap_guard.rb
|
|
163
176
|
- lib/jetstream_bridge/topology/stream.rb
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'core/model_codec_setup'
|
|
4
|
-
require_relative 'core/logging'
|
|
5
|
-
|
|
6
|
-
module JetstreamBridge
|
|
7
|
-
# Rails integration for JetStream Bridge.
|
|
8
|
-
#
|
|
9
|
-
# This Railtie integrates JetStream Bridge with the Rails application lifecycle:
|
|
10
|
-
# - Startup: Connection is established when Rails initializers run (via configure)
|
|
11
|
-
# - Shutdown: Connection is closed when Rails shuts down (at_exit hook)
|
|
12
|
-
# - Restart: Puma/Unicorn workers get fresh connections on fork
|
|
13
|
-
#
|
|
14
|
-
class Railtie < ::Rails::Railtie
|
|
15
|
-
# Set up logger to use Rails.logger by default
|
|
16
|
-
# Note: configure() will call startup! which establishes the connection
|
|
17
|
-
initializer 'jetstream_bridge.logger', before: :initialize_logger do
|
|
18
|
-
JetstreamBridge.configure do |config|
|
|
19
|
-
config.logger ||= Rails.logger if defined?(Rails.logger)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Load ActiveRecord model tweaks after ActiveRecord is loaded
|
|
24
|
-
initializer 'jetstream_bridge.active_record', after: 'active_record.initialize_database' do
|
|
25
|
-
ActiveSupport.on_load(:active_record) do
|
|
26
|
-
ActiveSupport::Reloader.to_prepare { JetstreamBridge::ModelCodecSetup.apply! }
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Validate configuration and setup environment-specific behavior
|
|
31
|
-
initializer 'jetstream_bridge.setup', after: :load_config_initializers do |app|
|
|
32
|
-
app.config.after_initialize do
|
|
33
|
-
# Validate configuration in development/test
|
|
34
|
-
if Rails.env.development? || Rails.env.test?
|
|
35
|
-
begin
|
|
36
|
-
JetstreamBridge.config.validate! if JetstreamBridge.config.destination_app
|
|
37
|
-
rescue JetstreamBridge::ConfigurationError => e
|
|
38
|
-
Rails.logger.warn "[JetStream Bridge] Configuration warning: #{e.message}"
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Auto-enable test mode in test environment if NATS_URLS not set
|
|
43
|
-
if Rails.env.test? && ENV['NATS_URLS'].blank? && !(defined?(JetstreamBridge::TestHelpers) &&
|
|
44
|
-
JetstreamBridge::TestHelpers.respond_to?(:test_mode?) &&
|
|
45
|
-
JetstreamBridge::TestHelpers.test_mode?)
|
|
46
|
-
Rails.logger.info '[JetStream Bridge] Auto-enabling test mode (NATS_URLS not set)'
|
|
47
|
-
require_relative 'test_helpers'
|
|
48
|
-
JetstreamBridge::TestHelpers.enable_test_mode!
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Log helpful connection info in development
|
|
52
|
-
if Rails.env.development? && JetstreamBridge.connected?
|
|
53
|
-
conn_state = JetstreamBridge::Connection.instance.state
|
|
54
|
-
Rails.logger.info "[JetStream Bridge] Connection state: #{conn_state}"
|
|
55
|
-
Rails.logger.info "[JetStream Bridge] Connected to: #{JetstreamBridge.config.nats_urls}"
|
|
56
|
-
Rails.logger.info "[JetStream Bridge] Stream: #{JetstreamBridge.config.stream_name}"
|
|
57
|
-
Rails.logger.info "[JetStream Bridge] Publishing to: #{JetstreamBridge.config.source_subject}"
|
|
58
|
-
Rails.logger.info "[JetStream Bridge] Consuming from: #{JetstreamBridge.config.destination_subject}"
|
|
59
|
-
end
|
|
60
|
-
rescue StandardError => e
|
|
61
|
-
# Don't fail app initialization for logging errors
|
|
62
|
-
Rails.logger.debug "[JetStream Bridge] Setup logging skipped: #{e.message}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Register shutdown hook for graceful cleanup
|
|
67
|
-
# This runs when Rails shuts down (Ctrl+C, SIGTERM, etc.)
|
|
68
|
-
config.after_initialize do
|
|
69
|
-
at_exit do
|
|
70
|
-
JetstreamBridge.shutdown!
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Add console helper methods
|
|
75
|
-
console do
|
|
76
|
-
Rails.logger.info "[JetStream Bridge] Loaded v#{JetstreamBridge::VERSION}"
|
|
77
|
-
Rails.logger.info '[JetStream Bridge] Use JetstreamBridge.health_check to check status'
|
|
78
|
-
Rails.logger.info '[JetStream Bridge] Use JetstreamBridge.shutdown! to gracefully disconnect'
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Load rake tasks
|
|
82
|
-
rake_tasks do
|
|
83
|
-
load File.expand_path('tasks/install.rake', __dir__)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Add generators
|
|
87
|
-
generators do
|
|
88
|
-
require 'generators/jetstream_bridge/health_check/health_check_generator'
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|