bitfab 0.20.2 → 0.21.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2428cc39dcd97d154e36ba9792628478e86a4b4dde5101c79d37ebb1635378f
4
- data.tar.gz: effa0dba40674696ad3d9155615d9d9e2e40a3fe7f9aed9c8ee97516985e13c6
3
+ metadata.gz: 7536f774b491c131b04a135a41c5f753c7c507615e54aa675c314cff785b08df
4
+ data.tar.gz: 47e7804161bc40563f5aca99147ef43d2af1af6d73d22f6ad3ae3402ea4b51f4
5
5
  SHA512:
6
- metadata.gz: 5f172f0178829a08315ae1caf3de6ff4a22389b2f83dbf449721ca53ca3a466580af00c15bd5279dffc2c9d074aee2afd0e157733f9257987460ef8d101350c9
7
- data.tar.gz: 9c6af19d4ebac35d13280aeaa89ac6104cbff3020e24813e292e4170c6524016a0df943025f3ced5510345c863e4b86f9f027fe281912e99a6438f863dde9d28
6
+ metadata.gz: 4aed7d077e6aa0ca89e8130b526578276591e60b41ae10670dc14db4eaca6221c30481dcad84acb8d7dfd7e549b2b92aa2c5a750efa36c4df85224b01360fe19
7
+ data.tar.gz: d73a3933eceba9c705fdab9f8b38f9f46766e026e59cdf61ee0ca2ea49a01ec4e5029fcbc87161a0a16602a2365ef3eeddba1acff27e659bf8fcf69b08d85138
data/lib/bitfab/client.rb CHANGED
@@ -59,14 +59,21 @@ module Bitfab
59
59
  # onto the method's current signature when its shape changed after the
60
60
  # traces were captured. Receives (args, kwargs, ctx) where ctx is
61
61
  # { trace_id:, source_span_id: }, and returns [new_args, new_kwargs].
62
+ # @param on_progress [#call, nil] optional callback invoked once per item as
63
+ # it finishes, with a running-totals hash { completed:, total:, succeeded:,
64
+ # errored: }. Use it to render replay progress (e.g. a terminal progress
65
+ # bar). Replay does not know pass/fail yet, so the totals only distinguish
66
+ # items whose method ran (:succeeded) from items that raised (:errored).
67
+ # A raising callback never crashes the run.
62
68
  # @return [Hash] with :items, :test_run_id, :test_run_url
63
69
  def replay(receiver, method_name, trace_function_key:, limit: nil, trace_ids: nil, max_concurrency: 10,
64
70
  code_change_description: nil, code_change_files: nil, experiment_group_id: nil, dataset_id: nil, mock: "none",
65
- adapt_inputs: nil, environment: nil)
71
+ adapt_inputs: nil, environment: nil, on_progress: nil)
66
72
  Replay.run(
67
73
  self, receiver, method_name,
68
74
  trace_function_key:, limit:, trace_ids:, max_concurrency:,
69
- code_change_description:, code_change_files:, experiment_group_id:, dataset_id:, mock:, adapt_inputs:, environment:
75
+ code_change_description:, code_change_files:, experiment_group_id:, dataset_id:, mock:, adapt_inputs:, environment:,
76
+ on_progress:
70
77
  )
71
78
  end
72
79
 
data/lib/bitfab/replay.rb CHANGED
@@ -100,10 +100,14 @@ module Bitfab
100
100
  # { trace_id:, source_span_id: }, and returns [new_args, new_kwargs]. Runs
101
101
  # per item inside the same rescue as the method, so a raising adapter sets
102
102
  # that item's :error rather than crashing the run.
103
+ # @param on_progress [#call, nil] optional callback invoked once per item as
104
+ # it finishes, with a running-totals hash { completed:, total:, succeeded:,
105
+ # errored: }. Use it to render replay progress (e.g. a terminal progress
106
+ # bar). A raising callback never crashes the run.
103
107
  # @return [Hash] with :items, :test_run_id, :test_run_url
104
108
  def run(client, receiver, method_name, trace_function_key:, limit: nil, trace_ids: nil, max_concurrency: 10,
105
109
  code_change_description: nil, code_change_files: nil, experiment_group_id: nil, dataset_id: nil, mock: "none",
106
- adapt_inputs: nil, environment: nil)
110
+ adapt_inputs: nil, environment: nil, on_progress: nil)
107
111
  unless MOCK_STRATEGIES.include?(mock.to_s)
108
112
  raise ArgumentError, "Invalid mock strategy '#{mock}'. Must be one of: #{MOCK_STRATEGIES.join(", ")}"
109
113
  end
@@ -157,7 +161,7 @@ module Bitfab
157
161
 
158
162
  result_items = if server_items.any?
159
163
  process_items(http_client, server_items, receiver, method_name, test_run_id, max_concurrency, mock.to_s,
160
- adapt_inputs, include_db_branch_lease)
164
+ adapt_inputs, include_db_branch_lease, on_progress:)
161
165
  else
162
166
  []
163
167
  end
@@ -237,13 +241,39 @@ module Bitfab
237
241
 
238
242
  # Process all replay items, optionally in parallel using threads.
239
243
  def process_items(http_client, server_items, receiver, method_name, test_run_id, max_concurrency, mock_strategy,
240
- adapt_inputs = nil, include_db_branch_lease = false)
244
+ adapt_inputs = nil, include_db_branch_lease = false, on_progress: nil)
241
245
  concurrency = max_concurrency || server_items.length
242
246
 
247
+ # Reports running totals once per item as it settles. In the parallel
248
+ # path it runs from worker threads, so the mutex both makes the counter
249
+ # updates safe and serializes the user's callback (never called
250
+ # concurrently). A raising callback is swallowed: progress UI must never
251
+ # crash the run.
252
+ total = server_items.length
253
+ progress_mutex = Mutex.new
254
+ completed = 0
255
+ succeeded = 0
256
+ errored = 0
257
+ report = lambda do |result|
258
+ return unless on_progress
259
+
260
+ progress_mutex.synchronize do
261
+ completed += 1
262
+ result[:error].nil? ? (succeeded += 1) : (errored += 1)
263
+ begin
264
+ on_progress.call({completed:, total:, succeeded:, errored:})
265
+ rescue => e
266
+ warn "Bitfab: replay on_progress callback raised: #{e.message}"
267
+ end
268
+ end
269
+ end
270
+
243
271
  if concurrency <= 1
244
272
  server_items.map do |item|
245
- process_single_item(http_client, item, receiver, method_name, test_run_id, mock_strategy, adapt_inputs,
246
- include_db_branch_lease)
273
+ result = process_single_item(http_client, item, receiver, method_name, test_run_id, mock_strategy,
274
+ adapt_inputs, include_db_branch_lease)
275
+ report.call(result)
276
+ result
247
277
  end
248
278
  else
249
279
  results_mutex = Mutex.new
@@ -260,6 +290,7 @@ module Bitfab
260
290
  result = process_single_item(http_client, item, receiver, method_name, test_run_id, mock_strategy,
261
291
  adapt_inputs, include_db_branch_lease)
262
292
  results_mutex.synchronize { results[idx] = result }
293
+ report.call(result)
263
294
  end
264
295
  end
265
296
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.20.2"
4
+ VERSION = "0.21.0"
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.20.2
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team