isolator 1.1.2 → 1.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +19 -0
- data/lib/isolator/database_cleaner_support.rb +16 -2
- data/lib/isolator/orm_adapters/active_support_transaction_subscriber.rb +19 -9
- data/lib/isolator/plugins/database_subtransactions.rb +20 -0
- data/lib/isolator/version.rb +1 -1
- data/lib/isolator.rb +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05b72beb85efc1ddfeb64209365e3b2326e346cce686a614349088a05406b2b7
|
|
4
|
+
data.tar.gz: 8679de3ba5f24b833054ee47a0515a8ce340fbb57880d6bf00dfa9d47ad57718
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20351d43476587b537082c2e0f83a01813ec9f8f57971eedd5251bc27723b276cfe8b6c5e4c930169e309fe0144f117684393b1faabae29a890af6f482cd2224
|
|
7
|
+
data.tar.gz: 8f6ed452926f6f5e955537a5de95b2a67569153ab54a79ccb20b98fb37a775e0398f7e8be285dd39ab31750548271921047b4afd417b254a8bbfa0f600be84a4
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## master
|
|
4
4
|
|
|
5
|
+
## 1.2.1 (2026-07-16)
|
|
6
|
+
|
|
7
|
+
- Fix handling "finish" events for untracked (lazy) transactions. ([@sawirricardo][])
|
|
8
|
+
|
|
9
|
+
## 1.2.0 (2025-11-07)
|
|
10
|
+
|
|
11
|
+
- Use `ActiveRecord::Base.lease_connection` instead of `ActiveRecord::Base.connection`, if available. ([@viralpraxis][])
|
|
12
|
+
|
|
13
|
+
- Add ability to limit subtransaction amount. ([@dnamsons][])
|
|
14
|
+
|
|
15
|
+
This feature is disabled by default, opt-in via: `Isolator.config.max_subtransactions_depth = :desired_depth`.
|
|
16
|
+
|
|
5
17
|
## 1.1.2 (2025-10-16)
|
|
6
18
|
|
|
7
19
|
- Fix `database_cleaner` support: require `base.rb` explicitly. ([@viralpraxis][])
|
|
@@ -161,3 +173,5 @@ This, for example, makes Isolator compatible with Rails multi-database apps.
|
|
|
161
173
|
[@tagirahmad]: https://github.com/tagirahmad
|
|
162
174
|
[@arthurWD]: https://github.com/arthurWD
|
|
163
175
|
[@joshuay03]: https://github.com/joshuay03
|
|
176
|
+
[@viralpraxis]: https://github.com/viralpraxis
|
|
177
|
+
[@sawirricardo]: https://github.com/sawirricardo
|
data/README.md
CHANGED
|
@@ -109,6 +109,9 @@ Isolator.configure do |config|
|
|
|
109
109
|
|
|
110
110
|
# Turn on/off raising exceptions for simultaneous transactions to different databases
|
|
111
111
|
config.disallow_per_thread_concurrent_transactions = false
|
|
112
|
+
|
|
113
|
+
# Limit the amount of allowed nested transactions
|
|
114
|
+
config.max_subtransactions_depth = 5
|
|
112
115
|
end
|
|
113
116
|
```
|
|
114
117
|
|
|
@@ -332,6 +335,22 @@ The reason is that Rails started using a [separate connection pool for advisory
|
|
|
332
335
|
|
|
333
336
|
To fix this disable migrations advisory locks by adding `advisory_locks: false` to your database configuration in `(spec|test)/internal/config/database.yml`.
|
|
334
337
|
|
|
338
|
+
## ActionMailer jobs
|
|
339
|
+
|
|
340
|
+
Rails 7.2 added support for the `enqueue_after_transaction_commit` configuration option, which ensures that jobs are enqueued only after all transactions have been committed. One gotcha that may lead to Isolator offenses is that `ActionMailer::MailDeliveryJob` inherits directly from `ActiveJob::Base`, rather than from your application’s top-level `ApplicationJob`.
|
|
341
|
+
|
|
342
|
+
To fix this, make sure `enqueue_after_transaction_commit` is set to true on `ActiveJob::Base`, or use the global `config.active_job.enqueue_after_transaction_commit setting` if your Rails version supports it.
|
|
343
|
+
|
|
344
|
+
See https://github.com/palkan/isolator/issues/93 for details.
|
|
345
|
+
|
|
346
|
+
## Occasional test failures related to connection reaping
|
|
347
|
+
|
|
348
|
+
In some cases, connections may be reaped and replaced mid-test, which will most likely lead to test failures because Isolator currently does not track this situation.
|
|
349
|
+
|
|
350
|
+
One way to mitigate this issue is to disable ActiveRecord's connection pool reaping by setting `reaping_frequency` to `nil`.
|
|
351
|
+
|
|
352
|
+
See https://github.com/palkan/isolator/issues/83 for details.
|
|
353
|
+
|
|
335
354
|
## Contributing
|
|
336
355
|
|
|
337
356
|
Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/isolator.
|
|
@@ -6,7 +6,9 @@ require "database_cleaner/active_record/transaction"
|
|
|
6
6
|
Module.new do
|
|
7
7
|
def start
|
|
8
8
|
super
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
connection_id = connection.object_id
|
|
11
|
+
|
|
10
12
|
Isolator.set_connection_threshold(
|
|
11
13
|
Isolator.transactions_threshold(connection_id) + 1,
|
|
12
14
|
connection_id
|
|
@@ -14,12 +16,24 @@ require "database_cleaner/active_record/transaction"
|
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def clean
|
|
17
|
-
connection_id =
|
|
19
|
+
connection_id = connection.object_id
|
|
20
|
+
|
|
18
21
|
Isolator.set_connection_threshold(
|
|
19
22
|
Isolator.transactions_threshold(connection_id) - 1,
|
|
20
23
|
connection_id
|
|
21
24
|
)
|
|
25
|
+
|
|
22
26
|
super
|
|
23
27
|
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def connection
|
|
32
|
+
if Gem::Version.new("7.2") <= Gem::Version.new(Rails::VERSION::STRING)
|
|
33
|
+
connection_class.lease_connection
|
|
34
|
+
else
|
|
35
|
+
connection_class.connection
|
|
36
|
+
end
|
|
37
|
+
end
|
|
24
38
|
end
|
|
25
39
|
)
|
|
@@ -13,16 +13,17 @@ module Isolator
|
|
|
13
13
|
def start(event, id, payload)
|
|
14
14
|
if event.start_with?("transaction.")
|
|
15
15
|
connection_id = extract_transaction_connection_id(payload)
|
|
16
|
+
stack = stacks[connection_id]
|
|
16
17
|
|
|
17
18
|
# transaction.active_record can be issued without a query (when we restart the transaction),
|
|
18
19
|
# so we should add a new one on the stack.
|
|
19
20
|
# Example: https://github.com/rails/rails/blob/ce49fa9b31cd4a21d43db39d0cea364bce28b51d/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L337
|
|
20
|
-
if
|
|
21
|
+
if stack.last == :raw
|
|
21
22
|
# Update the type of the last transaction event
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
stack.pop
|
|
24
|
+
stack << :transaction
|
|
24
25
|
else
|
|
25
|
-
|
|
26
|
+
stack << :transaction
|
|
26
27
|
Isolator.incr_transactions!(connection_id)
|
|
27
28
|
end
|
|
28
29
|
end
|
|
@@ -32,19 +33,23 @@ module Isolator
|
|
|
32
33
|
if event.start_with?("sql.")
|
|
33
34
|
if start_event?(payload[:sql])
|
|
34
35
|
connection_id = extract_connection_id(payload)
|
|
36
|
+
stack = stacks[connection_id]
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
stack << :raw
|
|
37
39
|
|
|
38
40
|
Isolator.incr_transactions!(connection_id)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
if finish_event?(payload[:sql])
|
|
42
44
|
connection_id = extract_connection_id(payload)
|
|
45
|
+
stack = stacks[connection_id]
|
|
43
46
|
|
|
44
47
|
# Decrement only if the transaction was started in the raw mode,
|
|
45
48
|
# otherwise we should wait for the "transaction" event
|
|
46
|
-
if
|
|
47
|
-
|
|
49
|
+
if stack.last == :raw
|
|
50
|
+
stack.pop
|
|
51
|
+
stacks.delete(connection_id) if stack.empty?
|
|
52
|
+
|
|
48
53
|
Isolator.decr_transactions!(connection_id)
|
|
49
54
|
end
|
|
50
55
|
end
|
|
@@ -52,9 +57,14 @@ module Isolator
|
|
|
52
57
|
|
|
53
58
|
if event.start_with?("transaction.")
|
|
54
59
|
connection_id = extract_transaction_connection_id(payload)
|
|
55
|
-
stacks[connection_id]
|
|
60
|
+
stack = stacks[connection_id]
|
|
61
|
+
|
|
62
|
+
if stack.last == :transaction
|
|
63
|
+
stack.pop
|
|
64
|
+
stacks.delete(connection_id) if stack.empty?
|
|
56
65
|
|
|
57
|
-
|
|
66
|
+
Isolator.decr_transactions!(connection_id)
|
|
67
|
+
end
|
|
58
68
|
end
|
|
59
69
|
end
|
|
60
70
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Isolator
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :max_subtransactions_depth
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class MaxSubtransactionsExceededError < UnsafeOperationError
|
|
9
|
+
MESSAGE = "Allowed subtransaction amount exceeded"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
Isolator.on_transaction_begin do |event|
|
|
13
|
+
next if Isolator.config.max_subtransactions_depth.nil?
|
|
14
|
+
|
|
15
|
+
depth = event[:depth]
|
|
16
|
+
next unless (depth - 1) > Isolator.config.max_subtransactions_depth
|
|
17
|
+
|
|
18
|
+
Isolator.notify(exception: MaxSubtransactionsExceededError.new, backtrace: caller)
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/isolator/version.rb
CHANGED
data/lib/isolator.rb
CHANGED
|
@@ -120,7 +120,7 @@ module Isolator
|
|
|
120
120
|
|
|
121
121
|
def decr_thresholds!
|
|
122
122
|
self.default_threshold -= 1
|
|
123
|
-
debug!("Thresholds were
|
|
123
|
+
debug!("Thresholds were decremented")
|
|
124
124
|
|
|
125
125
|
return unless state[:thresholds]
|
|
126
126
|
|
|
@@ -263,3 +263,4 @@ require "isolator/database_cleaner_support" if defined?(DatabaseCleaner)
|
|
|
263
263
|
|
|
264
264
|
# Built-in extensions
|
|
265
265
|
require "isolator/plugins/concurrent_database_transactions"
|
|
266
|
+
require "isolator/plugins/database_subtransactions"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: isolator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vladimir Dementyev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-07-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sniffer
|
|
@@ -318,6 +318,7 @@ files:
|
|
|
318
318
|
- lib/isolator/orm_adapters/active_support_transaction_subscriber.rb
|
|
319
319
|
- lib/isolator/orm_adapters/rom_active_support.rb
|
|
320
320
|
- lib/isolator/plugins/concurrent_database_transactions.rb
|
|
321
|
+
- lib/isolator/plugins/database_subtransactions.rb
|
|
321
322
|
- lib/isolator/railtie.rb
|
|
322
323
|
- lib/isolator/simple_hashie.rb
|
|
323
324
|
- lib/isolator/version.rb
|