bitfab 0.36.0 → 0.36.1

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: 1b5fdfbac8e62c59768ba554cd7c68b6fb7de3f1a37befd01a66cc6097821499
4
- data.tar.gz: 31bb825d1fcde3c946c5467bb6e1ccbd56816815b38ba4f3eb5395bdb5061907
3
+ metadata.gz: e0b827ad6e9bca08b3025f9c2419290910999a5985705369e6375aee8091232c
4
+ data.tar.gz: e6e0a414013d3bee0efda22415430d9690fe537973a36e5f3dda540fcda3d5e4
5
5
  SHA512:
6
- metadata.gz: efd78672cf98417507533b22bc0d4783ad7c29a18c4e9f419d95e328831275c26b4d15888642f07e19cd7a85b62babe55e223576d6a4885228fea4243ab84607
7
- data.tar.gz: 83dc9683122eefbe92fc747d783fb81351acc6ccef94e1c31f5ae2b391adac9d775832d9f56818cde2541817a4b8cde475cda44021b93a5f23bcbac9a010904a
6
+ metadata.gz: ee72cf5ed5c81ad34dbd4d980091523c90c7cb1d11fc716499ab5f604f1829f5653851350942b2cea6660e20e67c065ae8807e0778153a0ccf08a1397cc08491
7
+ data.tar.gz: 297efa6c3e5d9b1086536dd5e560168e9f9d4c638638b562a67d69ccb1c37253534da6447778032f93e186532f0a563eb7b7f41148eb6b9e0e2ac91c4ed2196e
data/lib/bitfab/client.rb CHANGED
@@ -407,6 +407,7 @@ module Bitfab
407
407
  {
408
408
  neon_branch_id: lease["neonBranchId"],
409
409
  snapshot_timestamp: lease["snapshotTimestamp"],
410
+ region: lease["region"],
410
411
  original_trace_id: replay_ctx[:source_bitfab_trace_id],
411
412
  # Deprecated wire alias, kept so this SDK still reports usage
412
413
  # against servers that predate the rename.
@@ -593,6 +594,9 @@ module Bitfab
593
594
  if db_snapshot_usage[:snapshot_timestamp]
594
595
  usage["snapshot_timestamp"] = db_snapshot_usage[:snapshot_timestamp]
595
596
  end
597
+ if db_snapshot_usage[:region]
598
+ usage["region"] = db_snapshot_usage[:region]
599
+ end
596
600
  if db_snapshot_usage[:original_trace_id]
597
601
  usage["original_trace_id"] = db_snapshot_usage[:original_trace_id]
598
602
  # Deprecated wire alias, kept so this SDK still reports usage
data/lib/bitfab/replay.rb CHANGED
@@ -62,10 +62,12 @@ module Bitfab
62
62
  # (via +database_url+). Reported on the trace
63
63
  # completion inside the +db_snapshot_usage+ record (its +accessed+
64
64
  # field) so the server can distinguish "branch was provisioned and
65
- # exposed" from "branch URL was actually consumed". Any future
66
- # consumption path that hands the URL to customer code by other means
67
- # (e.g. a process-isolated runner writing an env overlay) must also
68
- # set this.
65
+ # exposed" from "branch URL was actually consumed". Only an explicit
66
+ # +database_url+ read may set it. A path that hands the URL over by other
67
+ # means (e.g. a process-isolated runner writing an env overlay) must
68
+ # leave it alone: setting it there would make every such replay report
69
+ # accessed for free, and the flag would stop separating "branch was
70
+ # used" from "branch was offered".
69
71
  ctx[:db_branch_lease] = db_branch_lease if db_branch_lease
70
72
  ctx[:source_bitfab_trace_id] = source_bitfab_trace_id if source_bitfab_trace_id
71
73
  Thread.current[REPLAY_CONTEXT_KEY] = ctx
@@ -17,9 +17,20 @@ module Bitfab
17
17
  # protocol term). Its useful fields are exposed directly here so customer code
18
18
  # never sees the word.
19
19
  class ReplayBranch
20
+ # The provider's own id for this branch, e.g. for correlating with its console.
21
+ attr_reader :neon_branch_id
22
+
23
+ # Env var name the customer's app reads, e.g. "DATABASE_URL".
24
+ attr_reader :env_key
25
+
20
26
  # When this branch's URL stops being valid. ISO-8601.
21
27
  attr_reader :expires_at
22
28
 
29
+ # The instant this branch is pinned to: the source trace's wall clock, read
30
+ # just before the traced method ran. Compare it against the trace you meant
31
+ # to replay to confirm the branch is the right point in history.
32
+ attr_reader :snapshot_timestamp
33
+
23
34
  # Deep link to the branch in the provider console, if available.
24
35
  attr_reader :provider_console_url
25
36
 
@@ -36,13 +47,28 @@ module Bitfab
36
47
 
37
48
  # Built by Bitfab.current_replay_branch; never constructed by callers.
38
49
  def initialize(lease, trace_id, context)
39
- @expires_at = lease["expiresAt"]
40
- @provider_console_url = lease["providerConsoleUrl"]
41
- @read_only = lease["readOnly"]
42
- @region = lease["region"]
50
+ # Copy the lease wholesale minus the connection string, so a field the
51
+ # server starts sending reaches customer code without an SDK release.
52
+ # Everything set here must stay plain data: #database_url is the only
53
+ # member allowed to mark the branch as accessed.
54
+ # The internals are underscore-prefixed because the loop below writes an
55
+ # ivar per lease key: snake_case never emits a leading underscore, so no
56
+ # field the server invents can collide with them. A plain @fields would
57
+ # be clobbered mid-loop by a key named "fields", corrupting #as_json.
58
+ fields = {}
59
+ lease.each do |key, value|
60
+ next if key == "databaseUrl"
61
+
62
+ name = snake_case(key)
63
+ fields[name] = value
64
+ instance_variable_set(:"@#{name}", value)
65
+ define_singleton_method(name) { value } unless respond_to?(name)
66
+ end
43
67
  @trace_id = trace_id
44
- @url = lease["databaseUrl"]
45
- @context = context
68
+ fields["trace_id"] = trace_id
69
+ @_fields = fields.freeze
70
+ @_url = lease["databaseUrl"]
71
+ @_context = context
46
72
  freeze
47
73
  end
48
74
 
@@ -54,15 +80,39 @@ module Bitfab
54
80
  # was actually used". The other readers inspect the lease without exposing
55
81
  # the connection string, so they deliberately do not record anything.
56
82
  def database_url
57
- @context[:db_snapshot_accessed] = true
58
- @url
83
+ @_context[:db_snapshot_accessed] = true
84
+ @_url
59
85
  end
60
86
 
61
87
  # Redact the connection string so a logged or inspected branch cannot leak it.
62
88
  def inspect
63
89
  "#<Bitfab::ReplayBranch trace_id=#{@trace_id.inspect} " \
64
90
  "expires_at=#{@expires_at.inspect} region=#{@region.inspect} " \
65
- "read_only=#{@read_only.inspect}>"
91
+ "read_only=#{@read_only.inspect} " \
92
+ "snapshot_timestamp=#{@snapshot_timestamp.inspect}>"
93
+ end
94
+
95
+ # ActiveSupport gives every object a +to_json+ that serializes its instance
96
+ # variables, so under Rails a branch reaching a log line or an API response
97
+ # would carry the connection string and the whole replay context. Serialize
98
+ # the exposed fields only, the same set +inspect+ shows.
99
+ def as_json(_options = nil)
100
+ @_fields.dup
101
+ end
102
+
103
+ def to_json(*args)
104
+ as_json.to_json(*args)
105
+ end
106
+
107
+ private
108
+
109
+ # Two passes so a run of capitals stays one word: "dbURL" is "db_url", not
110
+ # "db_u_r_l". Must match the Python SDK's conversion exactly, or the same
111
+ # server field would arrive under different names in the two SDKs.
112
+ def snake_case(key)
113
+ key.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
114
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
115
+ .downcase
66
116
  end
67
117
  end
68
118
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.36.0"
4
+ VERSION = "0.36.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitfab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.36.0
4
+ version: 0.36.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team