after_commit_everywhere 1.2.0 → 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 +16 -0
- data/Gemfile.lock +69 -74
- data/lib/after_commit_everywhere/version.rb +1 -1
- data/lib/after_commit_everywhere.rb +20 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c67c4fd8f55095680c0519cef506d1b7296059b2dd4ce3c94c2a8787cc82c32e
|
4
|
+
data.tar.gz: e6feb83c65aa88072e56872105cf9511fccd9d4f5410afb9b9fc7060c768b79a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1679f32b243651bacc0d2966b4d72b67c1fe190f5a9165702ca11c9edd872b9bec0bd63fd0136b179a4255c5e98f9c957ce3fd67c7ce3454dbd1e201bcf0e01
|
7
|
+
data.tar.gz: c779815fd32f8e90f1ec01df87eab0a90a2425ad7e738d285d636b6e4762a0d7cb380f423a44087458dd2fdf533df57b8b78bc803ecb9858bf0eac70722cdb34
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## 1.2.1 (2022-06-10)
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
- Connection leak from the connection pool when `after_commit` called outside Rails executor without connection checked out
|
12
|
+
|
13
|
+
Usually all invocations of `after_commit` (whether it happens during serving HTTP request in Rails controller or performing job in Sidekiq worker process) are made inside [Rails executor](https://guides.rubyonrails.org/threading_and_code_execution.html#executor) which checks in any connections back to the connection pool that were checked out inside its block.
|
14
|
+
|
15
|
+
However, in cases when a) `after_commit` was called outside of Rails executor (3-rd party gems or non-Rails apps using ActiveRecord) **and** b) database connection hasn't been checked out yet, then connection will be checked out by `after_commit` implicitly by call to `ActiveRecord::Base.connection` and not checked in back afterwards causing it to _leak_ from the connection pool.
|
16
|
+
|
17
|
+
But in that case we can be sure that there is no transaction in progress ('cause one need to checkout connection and issue `BEGIN` to it), so we don't need to check it out at all and can fast-forward to `without_tx` action.
|
18
|
+
|
19
|
+
See discussion at [issue #20](https://github.com/Envek/after_commit_everywhere/issues/20) for details.
|
20
|
+
|
21
|
+
[Pull request #21](https://github.com/Envek/after_commit_everywhere/pull/21) by [@Envek][].
|
22
|
+
|
7
23
|
## 1.2.0 (2022-03-26)
|
8
24
|
|
9
25
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -1,78 +1,74 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
after_commit_everywhere (1.
|
4
|
+
after_commit_everywhere (1.2.0)
|
5
5
|
activerecord (>= 4.2)
|
6
6
|
activesupport
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
actioncable (7.0.
|
12
|
-
actionpack (= 7.0.
|
13
|
-
activesupport (= 7.0.
|
11
|
+
actioncable (7.0.3)
|
12
|
+
actionpack (= 7.0.3)
|
13
|
+
activesupport (= 7.0.3)
|
14
14
|
nio4r (~> 2.0)
|
15
15
|
websocket-driver (>= 0.6.1)
|
16
|
-
actionmailbox (7.0.
|
17
|
-
actionpack (= 7.0.
|
18
|
-
activejob (= 7.0.
|
19
|
-
activerecord (= 7.0.
|
20
|
-
activestorage (= 7.0.
|
21
|
-
activesupport (= 7.0.
|
16
|
+
actionmailbox (7.0.3)
|
17
|
+
actionpack (= 7.0.3)
|
18
|
+
activejob (= 7.0.3)
|
19
|
+
activerecord (= 7.0.3)
|
20
|
+
activestorage (= 7.0.3)
|
21
|
+
activesupport (= 7.0.3)
|
22
22
|
mail (>= 2.7.1)
|
23
23
|
net-imap
|
24
24
|
net-pop
|
25
25
|
net-smtp
|
26
|
-
actionmailer (7.0.
|
27
|
-
actionpack (= 7.0.
|
28
|
-
actionview (= 7.0.
|
29
|
-
activejob (= 7.0.
|
30
|
-
activesupport (= 7.0.
|
26
|
+
actionmailer (7.0.3)
|
27
|
+
actionpack (= 7.0.3)
|
28
|
+
actionview (= 7.0.3)
|
29
|
+
activejob (= 7.0.3)
|
30
|
+
activesupport (= 7.0.3)
|
31
31
|
mail (~> 2.5, >= 2.5.4)
|
32
32
|
net-imap
|
33
33
|
net-pop
|
34
34
|
net-smtp
|
35
35
|
rails-dom-testing (~> 2.0)
|
36
|
-
actionpack (7.0.
|
37
|
-
actionview (= 7.0.
|
38
|
-
activesupport (= 7.0.
|
36
|
+
actionpack (7.0.3)
|
37
|
+
actionview (= 7.0.3)
|
38
|
+
activesupport (= 7.0.3)
|
39
39
|
rack (~> 2.0, >= 2.2.0)
|
40
40
|
rack-test (>= 0.6.3)
|
41
41
|
rails-dom-testing (~> 2.0)
|
42
42
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
43
|
-
actiontext (7.0.
|
44
|
-
actionpack (= 7.0.
|
45
|
-
activerecord (= 7.0.
|
46
|
-
activestorage (= 7.0.
|
47
|
-
activesupport (= 7.0.
|
43
|
+
actiontext (7.0.3)
|
44
|
+
actionpack (= 7.0.3)
|
45
|
+
activerecord (= 7.0.3)
|
46
|
+
activestorage (= 7.0.3)
|
47
|
+
activesupport (= 7.0.3)
|
48
48
|
globalid (>= 0.6.0)
|
49
49
|
nokogiri (>= 1.8.5)
|
50
|
-
actionview (7.0.
|
51
|
-
activesupport (= 7.0.
|
50
|
+
actionview (7.0.3)
|
51
|
+
activesupport (= 7.0.3)
|
52
52
|
builder (~> 3.1)
|
53
53
|
erubi (~> 1.4)
|
54
54
|
rails-dom-testing (~> 2.0)
|
55
55
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
56
|
-
|
57
|
-
|
58
|
-
activemodel (>= 3.0.2, < 7.1)
|
59
|
-
activesupport (>= 3.0.2, < 7.1)
|
60
|
-
activejob (7.0.2.3)
|
61
|
-
activesupport (= 7.0.2.3)
|
56
|
+
activejob (7.0.3)
|
57
|
+
activesupport (= 7.0.3)
|
62
58
|
globalid (>= 0.3.6)
|
63
|
-
activemodel (7.0.
|
64
|
-
activesupport (= 7.0.
|
65
|
-
activerecord (7.0.
|
66
|
-
activemodel (= 7.0.
|
67
|
-
activesupport (= 7.0.
|
68
|
-
activestorage (7.0.
|
69
|
-
actionpack (= 7.0.
|
70
|
-
activejob (= 7.0.
|
71
|
-
activerecord (= 7.0.
|
72
|
-
activesupport (= 7.0.
|
59
|
+
activemodel (7.0.3)
|
60
|
+
activesupport (= 7.0.3)
|
61
|
+
activerecord (7.0.3)
|
62
|
+
activemodel (= 7.0.3)
|
63
|
+
activesupport (= 7.0.3)
|
64
|
+
activestorage (7.0.3)
|
65
|
+
actionpack (= 7.0.3)
|
66
|
+
activejob (= 7.0.3)
|
67
|
+
activerecord (= 7.0.3)
|
68
|
+
activesupport (= 7.0.3)
|
73
69
|
marcel (~> 1.0)
|
74
70
|
mini_mime (>= 1.1.0)
|
75
|
-
activesupport (7.0.
|
71
|
+
activesupport (7.0.3)
|
76
72
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
77
73
|
i18n (>= 1.6, < 2)
|
78
74
|
minitest (>= 5.1)
|
@@ -90,16 +86,16 @@ GEM
|
|
90
86
|
crass (1.0.6)
|
91
87
|
diff-lcs (1.5.0)
|
92
88
|
digest (3.1.0)
|
89
|
+
dry-initializer (3.1.1)
|
93
90
|
erubi (1.10.0)
|
94
91
|
globalid (1.0.0)
|
95
92
|
activesupport (>= 5.0)
|
96
93
|
i18n (1.10.0)
|
97
94
|
concurrent-ruby (~> 1.0)
|
98
|
-
io-wait (0.2.1)
|
99
95
|
isolator (0.8.0)
|
100
96
|
sniffer (>= 0.3.1)
|
101
97
|
jaro_winkler (1.5.4)
|
102
|
-
loofah (2.
|
98
|
+
loofah (2.18.0)
|
103
99
|
crass (~> 1.0.2)
|
104
100
|
nokogiri (>= 1.5.9)
|
105
101
|
mail (2.7.1)
|
@@ -117,49 +113,48 @@ GEM
|
|
117
113
|
digest
|
118
114
|
net-protocol
|
119
115
|
timeout
|
120
|
-
net-protocol (0.1.
|
121
|
-
io-wait
|
116
|
+
net-protocol (0.1.3)
|
122
117
|
timeout
|
123
118
|
net-smtp (0.3.1)
|
124
119
|
digest
|
125
120
|
net-protocol
|
126
121
|
timeout
|
127
122
|
nio4r (2.5.8)
|
128
|
-
nokogiri (1.13.
|
123
|
+
nokogiri (1.13.6)
|
129
124
|
mini_portile2 (~> 2.8.0)
|
130
125
|
racc (~> 1.4)
|
131
126
|
parallel (1.22.1)
|
132
|
-
parser (3.1.
|
127
|
+
parser (3.1.2.0)
|
133
128
|
ast (~> 2.4.1)
|
134
129
|
pry (0.14.1)
|
135
130
|
coderay (~> 1.1)
|
136
131
|
method_source (~> 1.0)
|
137
132
|
racc (1.6.0)
|
138
|
-
rack (2.2.3)
|
133
|
+
rack (2.2.3.1)
|
139
134
|
rack-test (1.1.0)
|
140
135
|
rack (>= 1.0, < 3)
|
141
|
-
rails (7.0.
|
142
|
-
actioncable (= 7.0.
|
143
|
-
actionmailbox (= 7.0.
|
144
|
-
actionmailer (= 7.0.
|
145
|
-
actionpack (= 7.0.
|
146
|
-
actiontext (= 7.0.
|
147
|
-
actionview (= 7.0.
|
148
|
-
activejob (= 7.0.
|
149
|
-
activemodel (= 7.0.
|
150
|
-
activerecord (= 7.0.
|
151
|
-
activestorage (= 7.0.
|
152
|
-
activesupport (= 7.0.
|
136
|
+
rails (7.0.3)
|
137
|
+
actioncable (= 7.0.3)
|
138
|
+
actionmailbox (= 7.0.3)
|
139
|
+
actionmailer (= 7.0.3)
|
140
|
+
actionpack (= 7.0.3)
|
141
|
+
actiontext (= 7.0.3)
|
142
|
+
actionview (= 7.0.3)
|
143
|
+
activejob (= 7.0.3)
|
144
|
+
activemodel (= 7.0.3)
|
145
|
+
activerecord (= 7.0.3)
|
146
|
+
activestorage (= 7.0.3)
|
147
|
+
activesupport (= 7.0.3)
|
153
148
|
bundler (>= 1.15.0)
|
154
|
-
railties (= 7.0.
|
149
|
+
railties (= 7.0.3)
|
155
150
|
rails-dom-testing (2.0.3)
|
156
151
|
activesupport (>= 4.2.0)
|
157
152
|
nokogiri (>= 1.6)
|
158
|
-
rails-html-sanitizer (1.4.
|
153
|
+
rails-html-sanitizer (1.4.3)
|
159
154
|
loofah (~> 2.3)
|
160
|
-
railties (7.0.
|
161
|
-
actionpack (= 7.0.
|
162
|
-
activesupport (= 7.0.
|
155
|
+
railties (7.0.3)
|
156
|
+
actionpack (= 7.0.3)
|
157
|
+
activesupport (= 7.0.3)
|
163
158
|
method_source
|
164
159
|
rake (>= 12.2)
|
165
160
|
thor (~> 1.0)
|
@@ -176,10 +171,10 @@ GEM
|
|
176
171
|
rspec-expectations (3.11.0)
|
177
172
|
diff-lcs (>= 1.2.0, < 2.0)
|
178
173
|
rspec-support (~> 3.11.0)
|
179
|
-
rspec-mocks (3.11.
|
174
|
+
rspec-mocks (3.11.1)
|
180
175
|
diff-lcs (>= 1.2.0, < 2.0)
|
181
176
|
rspec-support (~> 3.11.0)
|
182
|
-
rspec-rails (5.1.
|
177
|
+
rspec-rails (5.1.2)
|
183
178
|
actionpack (>= 5.2)
|
184
179
|
activesupport (>= 5.2)
|
185
180
|
railties (>= 5.2)
|
@@ -196,15 +191,15 @@ GEM
|
|
196
191
|
rexml
|
197
192
|
ruby-progressbar (~> 1.7)
|
198
193
|
unicode-display_width (>= 1.4.0, < 2.0)
|
199
|
-
ruby-next-core (0.15.
|
194
|
+
ruby-next-core (0.15.1)
|
200
195
|
ruby-progressbar (1.11.0)
|
201
|
-
sniffer (0.
|
202
|
-
active_attr (>= 0.10.2)
|
196
|
+
sniffer (0.5.0)
|
203
197
|
anyway_config (>= 1.0)
|
198
|
+
dry-initializer (~> 3)
|
204
199
|
sqlite3 (1.4.2)
|
205
|
-
strscan (3.0.
|
200
|
+
strscan (3.0.3)
|
206
201
|
thor (1.2.1)
|
207
|
-
timeout (0.
|
202
|
+
timeout (0.3.0)
|
208
203
|
tzinfo (2.0.4)
|
209
204
|
concurrent-ruby (~> 1.0)
|
210
205
|
unicode-display_width (1.8.0)
|
@@ -230,4 +225,4 @@ DEPENDENCIES
|
|
230
225
|
sqlite3 (~> 1.3, >= 1.3.6)
|
231
226
|
|
232
227
|
BUNDLED WITH
|
233
|
-
2.
|
228
|
+
2.3.10
|
@@ -30,7 +30,7 @@ module AfterCommitEverywhere
|
|
30
30
|
# Runs +callback+ after successful commit of outermost transaction for
|
31
31
|
# database +connection+.
|
32
32
|
#
|
33
|
-
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
33
|
+
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection to operate in. Defaults to +ActiveRecord::Base.connection+
|
34
34
|
# @param without_tx [Symbol] Determines the behavior of this function when
|
35
35
|
# called without an open transaction.
|
36
36
|
#
|
@@ -39,7 +39,7 @@ module AfterCommitEverywhere
|
|
39
39
|
# @param callback [#call] Callback to be executed
|
40
40
|
# @return void
|
41
41
|
def after_commit(
|
42
|
-
connection:
|
42
|
+
connection: nil,
|
43
43
|
without_tx: EXECUTE,
|
44
44
|
&callback
|
45
45
|
)
|
@@ -55,7 +55,7 @@ module AfterCommitEverywhere
|
|
55
55
|
#
|
56
56
|
# Available only since Ruby on Rails 5.0. See https://github.com/rails/rails/pull/18936
|
57
57
|
#
|
58
|
-
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
58
|
+
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection to operate in. Defaults to +ActiveRecord::Base.connection+
|
59
59
|
# @param without_tx [Symbol] Determines the behavior of this function when
|
60
60
|
# called without an open transaction.
|
61
61
|
#
|
@@ -64,7 +64,7 @@ module AfterCommitEverywhere
|
|
64
64
|
# @param callback [#call] Callback to be executed
|
65
65
|
# @return void
|
66
66
|
def before_commit(
|
67
|
-
connection:
|
67
|
+
connection: nil,
|
68
68
|
without_tx: WARN_AND_EXECUTE,
|
69
69
|
&callback
|
70
70
|
)
|
@@ -86,11 +86,11 @@ module AfterCommitEverywhere
|
|
86
86
|
# Caveat: do not raise +ActivRecord::Rollback+ in nested transaction block!
|
87
87
|
# See http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Nested+transactions
|
88
88
|
#
|
89
|
-
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
89
|
+
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection to operate in. Defaults to +ActiveRecord::Base.connection+
|
90
90
|
# @param callback [#call] Callback to be executed
|
91
91
|
# @return void
|
92
92
|
# @raise [NotInTransaction] if called outside transaction.
|
93
|
-
def after_rollback(connection:
|
93
|
+
def after_rollback(connection: nil, &callback)
|
94
94
|
register_callback(
|
95
95
|
connection: connection,
|
96
96
|
name: __method__,
|
@@ -100,7 +100,7 @@ module AfterCommitEverywhere
|
|
100
100
|
end
|
101
101
|
|
102
102
|
# @api private
|
103
|
-
def register_callback(connection
|
103
|
+
def register_callback(connection: nil, name:, without_tx:, callback:)
|
104
104
|
raise ArgumentError, "Provide callback to #{name}" unless callback
|
105
105
|
|
106
106
|
unless in_transaction?(connection)
|
@@ -116,14 +116,26 @@ module AfterCommitEverywhere
|
|
116
116
|
raise ArgumentError, "Invalid \"without_tx\": \"#{without_tx}\""
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
connection ||= default_connection
|
119
121
|
wrap = Wrap.new(connection: connection, "#{name}": callback)
|
120
122
|
connection.add_transaction_record(wrap)
|
121
123
|
end
|
122
124
|
|
123
125
|
# Helper method to determine whether we're currently in transaction or not
|
124
|
-
def in_transaction?(connection =
|
126
|
+
def in_transaction?(connection = nil)
|
127
|
+
# Don't establish new connection if not connected: we apparently not in transaction
|
128
|
+
return false unless connection || ActiveRecord::Base.connection_pool.connected?
|
129
|
+
|
130
|
+
connection ||= default_connection
|
125
131
|
# service transactions (tests and database_cleaner) are not joinable
|
126
132
|
connection.transaction_open? && connection.current_transaction.joinable?
|
127
133
|
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def default_connection
|
138
|
+
ActiveRecord::Base.connection
|
139
|
+
end
|
128
140
|
end
|
129
141
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: after_commit_everywhere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Novikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|