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 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