polyrun 2.2.0 → 2.2.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: 8b7bedc5bda9c9ee341927dab2ba6aedafaebe4c26ad73750d8ed7ad4845f4e3
4
- data.tar.gz: bac9cd71c5ab3372c0ff5dda891dd354a0ceaac3555f5949870ce8611646debc
3
+ metadata.gz: cf97ce76499f3784cf3a11d8e1ebf640631dc8247785ff74a518b70fb3218459
4
+ data.tar.gz: c4cc16110c1eb5696b1fab2fa771780a4102856909b8ecb620f2f2da3540b758
5
5
  SHA512:
6
- metadata.gz: fe09eaccf1eaf3fba5a998d49f2f2df9cfd6a1da6b1eef960e6cbe894f2269b05777be459fe394a67c3038d72750a8401ae8e224726901ac4bd437e3d01a93ed
7
- data.tar.gz: f8090b77fba080b7ca1996afeec0c2680ca26e0d0a4571453210f421f4921685bd8c5bcfeb79724556e377ff26968a914b52bf24b4a1a433a9500d656aa43f41
6
+ metadata.gz: 4d24dd153dcb88eb2e1bd7092fd47d72268ca6848061af4b64616fc6ea1307594086cfaa84e6ea06908a82b037b6404684315e66ed3cd7e923fbbaa50409e2f0
7
+ data.tar.gz: 9569227c3d67cc36eb4e79df95b36c9357aed6c79e853a428546d2c270ccd6accd900a6a8869b250cab3c2bbcf91021d29a4d9a9d5b53292355a6981229e4b64
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.2.1 (2026-07-13)
4
+
5
+ - Fix per-example timeout leaving ActiveRecord connection pools in a bad state after `Timeout` interrupts database I/O; disconnect all pools on timeout (adapter-agnostic).
6
+ - Fix `DEBUG_PROSOPITE=1`, `DEBUG_SQL` / `POLYRUN_DEBUG_SQL`, and `DEBUG_TRACE` / `POLYRUN_DEBUG_TRACE` requiring `POLYRUN_EXAMPLE_DEBUG=1`; each flag is standalone again.
7
+
3
8
  ## 2.2.0 (2026-07-13)
4
9
 
5
10
  - Fix `install_example_rails_logging!` raising `NameError` when example-debug Rails logging runs under `POLYRUN_EXAMPLE_DEBUG=1`.
@@ -69,14 +69,14 @@ Orchestration tracing stays on `DEBUG=1` / `POLYRUN_DEBUG=1`. Per-example toolin
69
69
 
70
70
  | Env | Effect |
71
71
  |--------|--------|
72
- | `POLYRUN_EXAMPLE_DEBUG=1` | Enable example debug installers |
72
+ | `POLYRUN_EXAMPLE_DEBUG=1` | Enable print helpers, Rails logging; disable per-example timeouts |
73
73
  | `POLYRUN_DEBUG_SQL=1` or `DEBUG_SQL=1` | Log mutating SQL |
74
74
  | `POLYRUN_DEBUG_TRACE=1` or `DEBUG_TRACE=1` | TracePoint under app root |
75
75
  | `DEBUG_PROSOPITE=1` | Prosopite N+1 scan when gem is loaded |
76
76
  | `DEBUG_LOG_LEVEL` | Rails / ActiveRecord logger severity: `debug`, `info`, `warn`, `error`, `fatal`, or Ruby Logger integers (`0` debug … `4` fatal); default `debug` |
77
- | `RSPEC_EXAMPLE_TIMEOUT_SEC` | Per-example timeout (disabled while example debug is on) |
77
+ | `RSPEC_EXAMPLE_TIMEOUT_SEC` | Per-example timeout (disabled while example debug is on); on timeout, ActiveRecord connection pools are disconnected so the next example gets fresh connections (any adapter) |
78
78
 
79
- In `spec_helper` / `spec/support`: `require "polyrun/rspec"` then `Polyrun::RSpec.install_sharded_formatter_compat!` (silences per-worker seed/summary/pending under `POLYRUN_SHARD_*`), `install_example_debug!`, `install_example_rails_logging!`, `install_example_timeout!`. Pair with `install_worker_ping!` for idle timeouts.
79
+ In `spec_helper` / `spec/support`: `require "polyrun/rspec"` then `Polyrun::RSpec.install_sharded_formatter_compat!` (silences per-worker seed/summary/pending under `POLYRUN_SHARD_*`), `install_example_debug!`, `install_example_rails_logging!`, `install_example_prosopite!`, `install_example_timeout!`. Pair with `install_worker_ping!` for idle timeouts.
80
80
 
81
81
  ## 6. Coverage and CI reports
82
82
 
@@ -26,7 +26,7 @@ module Polyrun
26
26
  Per-worker wall timeout: --worker-timeout SEC or POLYRUN_WORKER_TIMEOUT_SEC. Exit 124; parent stops remaining workers.
27
27
  Per-worker idle timeout: --worker-idle-timeout SEC or POLYRUN_WORKER_IDLE_TIMEOUT_SEC after a progress ping (POLYRUN_WORKER_PING_FILE). Enable pings in test setup. Exit 125. Optional periodic pings: POLYRUN_WORKER_PING_THREAD=1 (POLYRUN_WORKER_PING_INTERVAL_SEC).
28
28
  Worker output routing (opt-in): POLYRUN_WORKER_OUTPUT_ROUTING=1 or POLYRUN_WORKER_LOG_DIR; per-shard logs under tmp/polyrun/workers (POLYRUN_WORKER_OUTPUT_PREFIX=0 for log-only)
29
- Example debug (RSpec, opt-in): POLYRUN_EXAMPLE_DEBUG=1; POLYRUN_DEBUG_SQL / POLYRUN_DEBUG_TRACE
29
+ Example debug (RSpec, opt-in): POLYRUN_EXAMPLE_DEBUG=1 (print/Rails logging/timeouts); POLYRUN_DEBUG_SQL / DEBUG_SQL; POLYRUN_DEBUG_TRACE / DEBUG_TRACE; DEBUG_PROSOPITE=1
30
30
  Sharded formatter compat: silences per-worker seed, summary, and pending lines under POLYRUN_SHARD_* (see docs/SETUP_PROFILE.md)
31
31
  Orchestration warnings on process stderr: POLYRUN_ORCHESTRATION_STDERR=1
32
32
  Spec quality (opt-in): POLYRUN_SPEC_QUALITY=1; run-shards --merge-spec-quality; merge-spec-quality / report-spec-quality
@@ -0,0 +1,51 @@
1
+ module Polyrun
2
+ module RSpec
3
+ # Drops pooled connections after per-example Timeout interrupts database I/O.
4
+ # Uses only ActiveRecord connection-pool APIs (PostgreSQL, MySQL, SQLite, SQL Server, etc.).
5
+ module ActiveRecordTimeoutRecovery
6
+ module_function
7
+
8
+ def disconnect_all_connection_pools!
9
+ return unless active_record_loaded?
10
+
11
+ if defined?(ActiveRecord) && ActiveRecord.respond_to?(:disconnect_all!)
12
+ ActiveRecord.disconnect_all!
13
+ return
14
+ end
15
+
16
+ each_connection_pool(&:disconnect!)
17
+ end
18
+
19
+ def active_record_loaded?
20
+ defined?(ActiveRecord::Base) &&
21
+ ActiveRecord::Base.respond_to?(:connection_handler)
22
+ end
23
+
24
+ def each_connection_pool
25
+ connection_handlers.each do |handler|
26
+ pools_for(handler).each { |pool| yield pool }
27
+ end
28
+ end
29
+
30
+ def connection_handlers
31
+ base = ActiveRecord::Base
32
+ if base.respond_to?(:connection_handlers)
33
+ base.connection_handlers.values
34
+ else
35
+ [base.connection_handler]
36
+ end
37
+ end
38
+
39
+ def pools_for(handler)
40
+ if handler.respond_to?(:all_connection_pools)
41
+ handler.all_connection_pools
42
+ elsif handler.respond_to?(:connection_pool_list)
43
+ handler.connection_pool_list
44
+ else
45
+ []
46
+ end
47
+ end
48
+ private_class_method :active_record_loaded?, :each_connection_pool, :connection_handlers, :pools_for
49
+ end
50
+ end
51
+ end
@@ -6,9 +6,10 @@ module Polyrun
6
6
  module RSpec
7
7
  # Per-example RSpec debugging for local investigation (SQL, TracePoint, timeouts).
8
8
  #
9
- # +POLYRUN_EXAMPLE_DEBUG=1+ enables installers; +DEBUG=1+ / +POLYRUN_DEBUG=1+ trace orchestration only.
9
+ # +POLYRUN_EXAMPLE_DEBUG=1+ enables print helpers, Rails logging, and disables per-example timeouts.
10
10
  # +POLYRUN_DEBUG_SQL=1+ or legacy +DEBUG_SQL=1+ logs mutating SQL.
11
11
  # +POLYRUN_DEBUG_TRACE=1+ or legacy +DEBUG_TRACE=1+ traces :call/:raise under the app root.
12
+ # +DEBUG_PROSOPITE=1+ runs Prosopite N+1 scans when the gem is loaded.
12
13
  # +DEBUG_LOG_LEVEL+ accepts Ruby Logger severities as integers (0 debug … 4 fatal) or names.
13
14
  module ExampleDebug
14
15
  LOG_LEVEL_BY_NAME = {
@@ -26,15 +27,15 @@ module Polyrun
26
27
  end
27
28
 
28
29
  def sql_enabled?
29
- enabled? && (truthy?(ENV["POLYRUN_DEBUG_SQL"]) || truthy?(ENV["DEBUG_SQL"]))
30
+ truthy?(ENV["POLYRUN_DEBUG_SQL"]) || truthy?(ENV["DEBUG_SQL"])
30
31
  end
31
32
 
32
33
  def trace_enabled?
33
- enabled? && (truthy?(ENV["POLYRUN_DEBUG_TRACE"]) || truthy?(ENV["DEBUG_TRACE"]))
34
+ truthy?(ENV["POLYRUN_DEBUG_TRACE"]) || truthy?(ENV["DEBUG_TRACE"])
34
35
  end
35
36
 
36
37
  def prosopite_enabled?
37
- enabled? && truthy?(ENV["DEBUG_PROSOPITE"])
38
+ truthy?(ENV["DEBUG_PROSOPITE"])
38
39
  end
39
40
 
40
41
  def print_spec_enabled?
@@ -99,14 +100,22 @@ module Polyrun
99
100
  return if seconds <= 0
100
101
  return if example_timeout_disabled?
101
102
 
103
+ require_relative "active_record_timeout_recovery"
104
+
102
105
  rspec_config.around(:each) do |example|
103
- if example.metadata[:benchmark] || example.metadata[:slow]
104
- example.run
105
- else
106
- Timeout.timeout(seconds) { example.run }
106
+ timed_out = false
107
+ begin
108
+ if example.metadata[:benchmark] || example.metadata[:slow]
109
+ example.run
110
+ else
111
+ Timeout.timeout(seconds) { example.run }
112
+ end
113
+ rescue Timeout::Error
114
+ timed_out = true
115
+ raise "Example timed out after #{seconds}s (#{example.location})"
116
+ ensure
117
+ ActiveRecordTimeoutRecovery.disconnect_all_connection_pools! if timed_out
107
118
  end
108
- rescue Timeout::Error
109
- raise "Example timed out after #{seconds}s (#{example.location})"
110
119
  end
111
120
  end
112
121
 
@@ -1,3 +1,3 @@
1
1
  module Polyrun
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyrun
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Makarov
@@ -338,6 +338,7 @@ files:
338
338
  - lib/polyrun/reporting/rspec_failure_fragment_formatter.rb
339
339
  - lib/polyrun/reporting/rspec_junit.rb
340
340
  - lib/polyrun/rspec.rb
341
+ - lib/polyrun/rspec/active_record_timeout_recovery.rb
341
342
  - lib/polyrun/rspec/example_debug.rb
342
343
  - lib/polyrun/rspec/example_debug_instrumentation.rb
343
344
  - lib/polyrun/rspec/sharded_formatter_compat.rb