after_commit_everywhere 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22ac14ea80692909c9a464d9ad47d3c8d29950e020530a435e1def88763fd53f
4
- data.tar.gz: 761b7db7496e62837332714f55b9f9f916fd5b4d515515d18bab7947cb226270
3
+ metadata.gz: c67c4fd8f55095680c0519cef506d1b7296059b2dd4ce3c94c2a8787cc82c32e
4
+ data.tar.gz: e6feb83c65aa88072e56872105cf9511fccd9d4f5410afb9b9fc7060c768b79a
5
5
  SHA512:
6
- metadata.gz: 4d764c065a1d7fd99614e0e98c270a211a5a6fcb661068cb3edfaf34910d58b2a9754838fd6e5bf06f27e2caf6bb23209d8508153388de350250a52e26a466d9
7
- data.tar.gz: 20e3d66fdd8ecf32ac6087fe2d5142676577445c254bf750845d430ada830f5b7b121d35a76e486cd71468b11c67ce7f42ba721bf46db7f0370c13db0d177072
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.1.0)
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.2.3)
12
- actionpack (= 7.0.2.3)
13
- activesupport (= 7.0.2.3)
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.2.3)
17
- actionpack (= 7.0.2.3)
18
- activejob (= 7.0.2.3)
19
- activerecord (= 7.0.2.3)
20
- activestorage (= 7.0.2.3)
21
- activesupport (= 7.0.2.3)
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.2.3)
27
- actionpack (= 7.0.2.3)
28
- actionview (= 7.0.2.3)
29
- activejob (= 7.0.2.3)
30
- activesupport (= 7.0.2.3)
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.2.3)
37
- actionview (= 7.0.2.3)
38
- activesupport (= 7.0.2.3)
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.2.3)
44
- actionpack (= 7.0.2.3)
45
- activerecord (= 7.0.2.3)
46
- activestorage (= 7.0.2.3)
47
- activesupport (= 7.0.2.3)
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.2.3)
51
- activesupport (= 7.0.2.3)
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
- active_attr (0.15.4)
57
- actionpack (>= 3.0.2, < 7.1)
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.2.3)
64
- activesupport (= 7.0.2.3)
65
- activerecord (7.0.2.3)
66
- activemodel (= 7.0.2.3)
67
- activesupport (= 7.0.2.3)
68
- activestorage (7.0.2.3)
69
- actionpack (= 7.0.2.3)
70
- activejob (= 7.0.2.3)
71
- activerecord (= 7.0.2.3)
72
- activesupport (= 7.0.2.3)
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.2.3)
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.15.0)
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.2)
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.3)
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.1.0)
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.2.3)
142
- actioncable (= 7.0.2.3)
143
- actionmailbox (= 7.0.2.3)
144
- actionmailer (= 7.0.2.3)
145
- actionpack (= 7.0.2.3)
146
- actiontext (= 7.0.2.3)
147
- actionview (= 7.0.2.3)
148
- activejob (= 7.0.2.3)
149
- activemodel (= 7.0.2.3)
150
- activerecord (= 7.0.2.3)
151
- activestorage (= 7.0.2.3)
152
- activesupport (= 7.0.2.3)
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.2.3)
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.2)
153
+ rails-html-sanitizer (1.4.3)
159
154
  loofah (~> 2.3)
160
- railties (7.0.2.3)
161
- actionpack (= 7.0.2.3)
162
- activesupport (= 7.0.2.3)
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.0)
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.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.0)
194
+ ruby-next-core (0.15.1)
200
195
  ruby-progressbar (1.11.0)
201
- sniffer (0.4.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.1)
200
+ strscan (3.0.3)
206
201
  thor (1.2.1)
207
- timeout (0.2.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.2.25
228
+ 2.3.10
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AfterCommitEverywhere
4
- VERSION = "1.2.0"
4
+ VERSION = "1.2.1"
5
5
  end
@@ -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: ActiveRecord::Base.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: ActiveRecord::Base.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: ActiveRecord::Base.connection, &callback)
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:, name:, without_tx:, callback:)
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 = ActiveRecord::Base.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.0
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-03-26 00:00:00.000000000 Z
11
+ date: 2022-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord