bitfab 0.64.9 → 0.64.11

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: b270eed8dc307a13b2a5e98e723abb2a5433b0617eef2228c4a6c3e560cfc1c9
4
- data.tar.gz: cb3d9ce6dfca20c7bfff8b36f9577cf23fda6a8eeaf1e4fdd811c3fd375a30b1
3
+ metadata.gz: ca0982d902b32b704685f3942b2aa7a4f1caee10db462d4560674a291e0139c2
4
+ data.tar.gz: afe8094259621f9719aa45c2446f682b5c3a485443625663f4ddfc5086b730da
5
5
  SHA512:
6
- metadata.gz: 90d48fd92f1fd3eb0a913ea4b3070e677ac40fa0e5ec18b928fda31fa7e5e1158eaca47736d305eaee3a850800558cc2890d501596c3a37216ae8682f31acae7
7
- data.tar.gz: 493ca207e1e61d5737f1ec8efb6126e8e2f0f118090f797ddf5d5d709349632ebd1c6de7673c67ec99142e5226b16e459f1c9e3addfa05504db72a1238e44868
6
+ metadata.gz: fc314e448b508c5ecef57cb62736e77faef740a830f56cd5bfd3cc29e5209dc97df84a8b7e94641f9cd4c23a34311db60d4e64695c87c77bc1078dc05a1df115
7
+ data.tar.gz: 13c217d4efd1704e20315748e4b710f3d7ab92e351c5cc5c6e13af98f2c008a8bbf65a7e9315b304618e5750c6ce748aadebdab1df26c4f2b9d2d7ba20106bb8
@@ -83,6 +83,10 @@ module Bitfab
83
83
  end
84
84
 
85
85
  def get_simulation_plan
86
+ # Without a key the server answers 401, so skip the request entirely.
87
+ key = @api_key.respond_to?(:call) ? @api_key.call : @api_key
88
+ raise ArgumentError, SimulationPlan::NO_API_KEY if key.to_s.strip.empty?
89
+
86
90
  get("/api/sdk/sim-plan", timeout: SimulationPlan::READ_TIMEOUT)
87
91
  end
88
92
 
data/lib/bitfab/replay.rb CHANGED
@@ -464,7 +464,8 @@ module Bitfab
464
464
  # trace-ID mapping complete_replay builds would otherwise race the
465
465
  # in-flight batches and hand back nil for every item.
466
466
  delivered_trace_ids = preserve_replay_failure(result_items, experiment_id, full_experiment_url) do
467
- wait_for_replay_persistence(http_client, experiment_id, result_items.map { |item| item[:_sdk_trace_id] })
467
+ wait_for_replay_persistence(http_client, experiment_id, result_items.map { |item| item[:_sdk_trace_id] },
468
+ labels: replay_labels(result_items))
468
469
  end
469
470
 
470
471
  # Primary source for item[:trace_id]: the server's assigned traces.id, read
@@ -1243,7 +1244,7 @@ module Bitfab
1243
1244
  # repeat itself. Acks cannot settle a request that timed out client-side
1244
1245
  # after the server committed, so anything short of fully delivered falls
1245
1246
  # through to the server poll, which stays the authority there.
1246
- def wait_for_replay_persistence(http_client, experiment_id, sdk_trace_ids, timeout: nil)
1247
+ def wait_for_replay_persistence(http_client, experiment_id, sdk_trace_ids, timeout: nil, labels: {})
1247
1248
  timeout ||= PERSISTENCE_TIMEOUT_SECONDS
1248
1249
  trace_ids = sdk_trace_ids.compact
1249
1250
 
@@ -1286,15 +1287,29 @@ module Bitfab
1286
1287
  sleep((deadline - Otel.monotonic_now).clamp(0, PERSISTENCE_POLL_SECONDS))
1287
1288
  end
1288
1289
 
1289
- cause = if flushed
1290
- ""
1291
- else
1292
- " Delivery was also not confirmed before the flush deadline, so the " \
1293
- "spans likely never reached the server."
1290
+ missing.each do |trace_id|
1291
+ warn_unconfirmed_replay(unconfirmed_replay_warning(labels.fetch(trace_id, trace_id), timeout, flushed))
1292
+ end
1293
+ read_back_trace_ids
1294
+ end
1295
+
1296
+ def unconfirmed_replay_warning(label, seconds, flushed)
1297
+ "[bitfab] replay #{label} could not confirm all spans reached Bitfab within #{format("%g", seconds)}s. " \
1298
+ "The run continues; Bitfab will show this replay as capture incomplete." \
1299
+ "#{" Some spans likely never left this process." unless flushed}"
1300
+ end
1301
+
1302
+ def warn_unconfirmed_replay(message)
1303
+ Bitfab.count_delivery_problem(message)
1304
+ warn message
1305
+ rescue Exception # rubocop:disable Lint/RescueException
1306
+ nil
1307
+ end
1308
+
1309
+ def replay_labels(items)
1310
+ items.each_with_object({}) do |item, labels|
1311
+ labels[item[:_sdk_trace_id]] = "#{item[:original_trace_id]}##{item[:attempt]}" if item[:_sdk_trace_id]
1294
1312
  end
1295
- raise "Replay traces were not fully persisted before the delivery deadline " \
1296
- "(experiment #{experiment_id}, missing #{missing.length} of " \
1297
- "#{expected_span_counts.length} trace(s)).#{cause}"
1298
1313
  end
1299
1314
 
1300
1315
  # Normalize a complete-replay tokens hash (string-keyed JSON) into the
@@ -51,13 +51,13 @@ module Bitfab
51
51
  mock_overrides: overrides, dry_run: assignment.fetch("dry_run"))
52
52
  unless assignment["dry_run"]
53
53
  begin
54
- mapped = Replay.wait_for_replay_persistence(http, assignment.fetch("experiment_id"), [result[:_sdk_trace_id]], timeout: delivery_timeout)
54
+ mapped = Replay.wait_for_replay_persistence(http, assignment.fetch("experiment_id"), [result[:_sdk_trace_id]],
55
+ timeout: delivery_timeout, labels: Replay.replay_labels([result]))
55
56
  result[:trace_id] = mapped[result[:_sdk_trace_id]] || result[:trace_id]
56
57
  if result[:_sdk_trace_id] && result[:trace_id].nil?
57
58
  status = http.get_replay_status(assignment.fetch("experiment_id"), {result[:_sdk_trace_id] => 1})
58
59
  result[:trace_id] = status.fetch("traceIds", {})[result[:_sdk_trace_id]]
59
60
  end
60
- raise "Child replay trace persistence could not be confirmed" if result[:error].nil? && result[:trace_id].nil?
61
61
  rescue => error
62
62
  result[:replay_error] = error
63
63
  result[:error] = error.message
@@ -8,6 +8,7 @@ module Bitfab
8
8
  REFRESH_SECONDS = 60.0
9
9
  RETRY_SECONDS = 10.0
10
10
  MAX_HELD = 1000
11
+ NO_API_KEY = "no API key is set"
11
12
  @plans = ObjectSpace::WeakMap.new
12
13
  @plans_mutex = Mutex.new
13
14
  @plans_pid = Process.pid
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.64.9"
4
+ VERSION = "0.64.11"
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.64.9
4
+ version: 0.64.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team