You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.1 KiB
55 lines
2.1 KiB
From 4f4f8a705a8e713bceee8cacca52e9bce22e28dc Mon Sep 17 00:00:00 2001
|
|
From: "yuuji.yaginuma" <yuuji.yaginuma@gmail.com>
|
|
Date: Wed, 18 Dec 2019 19:00:29 +0900
|
|
Subject: [PATCH] Make `LoadInterlockAwareMonitor` work in Ruby 2.7
|
|
|
|
Currently `LoadInterlockAwareMonitorTest` does not pass with Ruby 2.7 [1].
|
|
This is due to the refactoring of the `monitor` done in Ruby 2.7 [2].
|
|
|
|
With this refactoring, the behavior of the method has changed from the
|
|
expected behavior in `LoadInterlockAwareMonitor`.
|
|
|
|
This patch also overwrites `synchronize` so that
|
|
`LoadInterlockAwareMonitor` works as expected.
|
|
|
|
[1]: https://buildkite.com/rails/rails/builds/65877#eec47af5-7595-47cb-97c0-30c589716176/996-2743
|
|
[2]: https://bugs.ruby-lang.org/issues/16255
|
|
---
|
|
.../load_interlock_aware_monitor.rb | 18 ++++++++++++++++++
|
|
1 file changed, 18 insertions(+)
|
|
|
|
diff --git a/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb b/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb
|
|
index a8455c00483f..480c34c64017 100644
|
|
--- a/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb
|
|
+++ b/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb
|
|
@@ -7,11 +7,29 @@ module Concurrency
|
|
# A monitor that will permit dependency loading while blocked waiting for
|
|
# the lock.
|
|
class LoadInterlockAwareMonitor < Monitor
|
|
+ EXCEPTION_NEVER = { Exception => :never }.freeze
|
|
+ EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
|
+ private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
|
+
|
|
# Enters an exclusive section, but allows dependency loading while blocked
|
|
def mon_enter
|
|
mon_try_enter ||
|
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
|
|
end
|
|
+
|
|
+ def synchronize
|
|
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
|
|
+ mon_enter
|
|
+
|
|
+ begin
|
|
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
|
|
+ yield
|
|
+ end
|
|
+ ensure
|
|
+ mon_exit
|
|
+ end
|
|
+ end
|
|
+ end
|
|
end
|
|
end
|
|
end
|