Class: Turbocable::NullAdapter
- Inherits:
-
Object
- Object
- Turbocable::NullAdapter
- Defined in:
- lib/turbocable/null_adapter.rb
Overview
A drop-in replacement for NatsConnection that records every publish call in an in-memory ring buffer instead of hitting NATS.
Usage in test suites
# spec_helper.rb / rails_helper.rb
RSpec.configure do |config|
config.around(:each) do |example|
Turbocable.configure { |c| c.adapter = :null }
example.run
Turbocable::NullAdapter.reset!
end
end
# In a spec:
it "broadcasts the payload" do
Turbocable.broadcast("chat_room_42", text: "hello")
recorded = Turbocable::NullAdapter.broadcasts
expect(recorded.size).to eq(1)
expect(recorded.first[:subject]).to eq("TURBOCABLE.chat_room_42")
end
Thread safety
All access to the shared ring buffer is serialized through a class-level Mutex. Instances of NullAdapter are stateless — they delegate recording to class-level state so that callers can inspect broadcasts without keeping a reference to the adapter instance.
Ring buffer
Older entries are evicted once the buffer reaches MAX_BUFFER records. This prevents unbounded memory growth in long-running test suites.
Defined Under Namespace
Classes: NullAck
Constant Summary collapse
- MAX_BUFFER =
Default maximum number of broadcast records kept in memory.
1_000
Class Method Summary collapse
-
.broadcasts ⇒ Array<Hash>
Returns a snapshot of all recorded broadcasts since the last
reset!. - .record(subject:, payload:, at:, buffer_size:) ⇒ Object private
-
.reset! ⇒ void
Clears all recorded broadcasts.
Instance Method Summary collapse
-
#close ⇒ void
No-op.
-
#initialize(buffer_size: MAX_BUFFER) ⇒ NullAdapter
constructor
A new instance of NullAdapter.
-
#key_value ⇒ Object
Not supported on the null adapter.
-
#ping(timeout: 2.0) ⇒ true
Always returns
true— the null adapter is always “healthy”. -
#publish(subject, bytes, timeout:) ⇒ NullAck
Records the publish in the class-level ring buffer and returns a fake ack.
Constructor Details
#initialize(buffer_size: MAX_BUFFER) ⇒ NullAdapter
Returns a new instance of NullAdapter.
77 78 79 |
# File 'lib/turbocable/null_adapter.rb', line 77 def initialize(buffer_size: MAX_BUFFER) @buffer_size = buffer_size end |
Class Method Details
.broadcasts ⇒ Array<Hash>
Returns a snapshot of all recorded broadcasts since the last reset!.
Each element is a Hash with keys:
-
:subject— the full NATS subject (e.g. “TURBOCABLE.chat_room_42”) -
:payload— encoded bytes as published -
:codec— alwaysnilat the adapter layer (codec is resolved byClientbefore reaching the adapter) -
:at—Timeof the publish call
55 56 57 |
# File 'lib/turbocable/null_adapter.rb', line 55 def broadcasts @mutex.synchronize { @broadcasts.dup } end |
.record(subject:, payload:, at:, buffer_size:) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
68 69 70 71 72 73 |
# File 'lib/turbocable/null_adapter.rb', line 68 def record(subject:, payload:, at:, buffer_size:) @mutex.synchronize do @broadcasts << {subject: subject, payload: payload, codec: nil, at: at} @broadcasts.shift while @broadcasts.size > buffer_size end end |
.reset! ⇒ void
This method returns an undefined value.
Clears all recorded broadcasts. Call this between test examples to prevent cross-example pollution. Thread-safe.
63 64 65 |
# File 'lib/turbocable/null_adapter.rb', line 63 def reset! @mutex.synchronize { @broadcasts.clear } end |
Instance Method Details
#close ⇒ void
This method returns an undefined value.
No-op. Satisfies the adapter interface so Turbocable.reset! can call close on the adapter without a conditional.
115 116 |
# File 'lib/turbocable/null_adapter.rb', line 115 def close end |
#key_value ⇒ Object
Not supported on the null adapter. Raises NotImplementedError so that callers don’t silently succeed when running against the null adapter in contexts where KV access is required (e.g. publish_public_key!).
105 106 107 108 109 |
# File 'lib/turbocable/null_adapter.rb', line 105 def key_value(*) raise NotImplementedError, "NullAdapter does not support key_value. " \ "Use the :nats adapter when you need KV access." end |
#ping(timeout: 2.0) ⇒ true
Always returns true — the null adapter is always “healthy”.
96 97 98 |
# File 'lib/turbocable/null_adapter.rb', line 96 def ping(timeout: 2.0) true end |
#publish(subject, bytes, timeout:) ⇒ NullAck
Records the publish in the class-level ring buffer and returns a fake ack.
87 88 89 90 |
# File 'lib/turbocable/null_adapter.rb', line 87 def publish(subject, bytes, timeout:) self.class.record(subject: subject, payload: bytes, at: Time.now, buffer_size: @buffer_size) NullAck.new end |