Class: Bitfab::ReplayBranch
- Inherits:
-
Object
- Object
- Bitfab::ReplayBranch
- Defined in:
- lib/bitfab/replay_branch.rb
Overview
The database branch a single replay item runs against.
Bitfab.current_replay_branch hands you one inside a replayed method when
the source trace carried a DB snapshot reference and the Bitfab service
resolved a branch from it. Outside a replay item, or when no branch was
resolved, that reader returns nil and your code keeps reading
ENV["DATABASE_URL"] the normal way.
Immutable and scoped to one item: the reader builds it from the thread-local replay context, so parallel replay items each see their own branch and no lease state lives on a long-lived object.
Internally the resolved per-item state is a DB branch lease (the SDK/server protocol term). Its useful fields are exposed directly here so customer code never sees the word.
Instance Attribute Summary collapse
-
#env_key ⇒ Object
readonly
Env var name the customer's app reads, e.g.
-
#expires_at ⇒ Object
readonly
When this branch's URL stops being valid.
-
#neon_branch_id ⇒ Object
readonly
The provider's own id for this branch, e.g.
-
#provider_console_url ⇒ Object
readonly
Deep link to the branch in the provider console, if available.
-
#read_only ⇒ Object
readonly
True if the branch is read-only.
-
#region ⇒ Object
readonly
The branch's region, e.g.
-
#snapshot_timestamp ⇒ Object
readonly
The instant this branch is pinned to: the source trace's wall clock, read just before the traced method ran.
-
#trace_id ⇒ Object
readonly
The historical trace ID that produced the input for this replay item.
Instance Method Summary collapse
-
#as_json(_options = nil) ⇒ Object
ActiveSupport gives every object a
to_jsonthat serializes its instance variables, so under Rails a branch reaching a log line or an API response would carry the connection string and the whole replay context. -
#database_url ⇒ Object
Connection string for this item's branch.
-
#initialize(lease, trace_id, context) ⇒ ReplayBranch
constructor
Built by Bitfab.current_replay_branch; never constructed by callers.
-
#inspect ⇒ Object
Redact the connection string so a logged or inspected branch cannot leak it.
- #to_json(*args) ⇒ Object
Constructor Details
#initialize(lease, trace_id, context) ⇒ ReplayBranch
Built by Bitfab.current_replay_branch; never constructed by callers.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/bitfab/replay_branch.rb', line 49 def initialize(lease, trace_id, context) # Copy the lease wholesale minus the connection string, so a field the # server starts sending reaches customer code without an SDK release. # Everything set here must stay plain data: #database_url is the only # member allowed to mark the branch as accessed. # The internals are underscore-prefixed because the loop below writes an # ivar per lease key: snake_case never emits a leading underscore, so no # field the server invents can collide with them. A plain @fields would # be clobbered mid-loop by a key named "fields", corrupting #as_json. fields = {} lease.each do |key, value| next if key == "databaseUrl" name = snake_case(key) fields[name] = value instance_variable_set(:"@#{name}", value) define_singleton_method(name) { value } unless respond_to?(name) end @trace_id = trace_id fields["trace_id"] = trace_id @_fields = fields.freeze @_url = lease["databaseUrl"] @_context = context freeze end |
Instance Attribute Details
#env_key ⇒ Object (readonly)
Env var name the customer's app reads, e.g. "DATABASE_URL".
24 25 26 |
# File 'lib/bitfab/replay_branch.rb', line 24 def env_key @env_key end |
#expires_at ⇒ Object (readonly)
When this branch's URL stops being valid. ISO-8601.
27 28 29 |
# File 'lib/bitfab/replay_branch.rb', line 27 def expires_at @expires_at end |
#neon_branch_id ⇒ Object (readonly)
The provider's own id for this branch, e.g. for correlating with its console.
21 22 23 |
# File 'lib/bitfab/replay_branch.rb', line 21 def neon_branch_id @neon_branch_id end |
#provider_console_url ⇒ Object (readonly)
Deep link to the branch in the provider console, if available.
35 36 37 |
# File 'lib/bitfab/replay_branch.rb', line 35 def provider_console_url @provider_console_url end |
#read_only ⇒ Object (readonly)
True if the branch is read-only. Use it to skip write operations during replay when the provider returned a read-only lease.
39 40 41 |
# File 'lib/bitfab/replay_branch.rb', line 39 def read_only @read_only end |
#region ⇒ Object (readonly)
The branch's region, e.g. "aws-us-east-1". A compute runs in its project's region, so a replay runner elsewhere pays that round trip on every query.
43 44 45 |
# File 'lib/bitfab/replay_branch.rb', line 43 def region @region end |
#snapshot_timestamp ⇒ Object (readonly)
The instant this branch is pinned to: the source trace's wall clock, read just before the traced method ran. Compare it against the trace you meant to replay to confirm the branch is the right point in history.
32 33 34 |
# File 'lib/bitfab/replay_branch.rb', line 32 def @snapshot_timestamp end |
#trace_id ⇒ Object (readonly)
The historical trace ID that produced the input for this replay item.
46 47 48 |
# File 'lib/bitfab/replay_branch.rb', line 46 def trace_id @trace_id end |
Instance Method Details
#as_json(_options = nil) ⇒ Object
ActiveSupport gives every object a to_json that serializes its instance
variables, so under Rails a branch reaching a log line or an API response
would carry the connection string and the whole replay context. Serialize
the exposed fields only, the same set inspect shows.
99 100 101 |
# File 'lib/bitfab/replay_branch.rb', line 99 def as_json( = nil) @_fields.dup end |
#database_url ⇒ Object
Connection string for this item's branch. Point your database client at it instead of the live database for the duration of the replayed call.
Reading it records on the trace that the replayed code obtained the branch URL, which is what separates "a branch was provisioned" from "the branch was actually used". The other readers inspect the lease without exposing the connection string, so they deliberately do not record anything.
82 83 84 85 |
# File 'lib/bitfab/replay_branch.rb', line 82 def database_url @_context[:db_snapshot_accessed] = true @_url end |
#inspect ⇒ Object
Redact the connection string so a logged or inspected branch cannot leak it.
88 89 90 91 92 93 |
# File 'lib/bitfab/replay_branch.rb', line 88 def inspect "#<Bitfab::ReplayBranch trace_id=#{@trace_id.inspect} " \ "expires_at=#{@expires_at.inspect} region=#{@region.inspect} " \ "read_only=#{@read_only.inspect} " \ "snapshot_timestamp=#{@snapshot_timestamp.inspect}>" end |
#to_json(*args) ⇒ Object
103 104 105 |
# File 'lib/bitfab/replay_branch.rb', line 103 def to_json(*args) as_json.to_json(*args) end |