|
3 | 3 | module Que
|
4 | 4 | module ActiveRecord
|
5 | 5 | class << self
|
| 6 | + def active_rails_executor? |
| 7 | + defined?(::Rails.application.executor) && ::Rails.application.executor.active? |
| 8 | + end |
| 9 | + |
6 | 10 | def wrap_in_rails_executor(&block)
|
7 | 11 | if defined?(::Rails.application.executor)
|
8 | 12 | ::Rails.application.executor.wrap(&block)
|
@@ -39,17 +43,36 @@ def call(job)
|
39 | 43 | yield
|
40 | 44 | end
|
41 | 45 |
|
42 |
| - # ActiveRecord will check out connections to the current thread when |
43 |
| - # queries are executed and not return them to the pool until |
44 |
| - # explicitly requested to. I'm not wild about this API design, and |
45 |
| - # it doesn't pose a problem for the typical case of workers using a |
46 |
| - # single PG connection (since we ensure that connection is checked |
47 |
| - # in and checked out responsibly), but since ActiveRecord supports |
48 |
| - # connections to multiple databases, it's easy for people using that |
49 |
| - # feature to unknowingly leak connections to other databases. So, |
50 |
| - # take the additional step of telling ActiveRecord to check in all |
51 |
| - # of the current thread's connections after each job is run. |
52 |
| - ::ActiveRecord::Base.clear_active_connections! unless job.class.resolve_que_setting(:run_synchronously) |
| 46 | + clear_active_connections_if_needed!(job) |
| 47 | + end |
| 48 | + |
| 49 | + private |
| 50 | + |
| 51 | + # ActiveRecord will check out connections to the current thread when |
| 52 | + # queries are executed and not return them to the pool until |
| 53 | + # explicitly requested to. I'm not wild about this API design, and |
| 54 | + # it doesn't pose a problem for the typical case of workers using a |
| 55 | + # single PG connection (since we ensure that connection is checked |
| 56 | + # in and checked out responsibly), but since ActiveRecord supports |
| 57 | + # connections to multiple databases, it's easy for people using that |
| 58 | + # feature to unknowingly leak connections to other databases. So, |
| 59 | + # take the additional step of telling ActiveRecord to check in all |
| 60 | + # of the current thread's connections after each job is run. |
| 61 | + def clear_active_connections_if_needed!(job) |
| 62 | + # don't clean in synchronous mode |
| 63 | + # see https://github.com/que-rb/que/pull/393 |
| 64 | + return if job.class.resolve_que_setting(:run_synchronously) |
| 65 | + |
| 66 | + # don't clear connections in nested jobs, |
| 67 | + # i.e. clear only if this is the outermost instance of |
| 68 | + # Que::ActiveRecord::Connection::JobMiddleware |
| 69 | + return if Que::ActiveRecord.active_rails_executor? |
| 70 | + |
| 71 | + if ::ActiveRecord.version >= Gem::Version.new('7.1') |
| 72 | + ::ActiveRecord::Base.connection_handler.clear_active_connections!(:all) |
| 73 | + else |
| 74 | + ::ActiveRecord::Base.clear_active_connections! |
| 75 | + end |
53 | 76 | end
|
54 | 77 | end
|
55 | 78 | end
|
|
0 commit comments