1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #30433 from y-yagi/fix_cant_modify_forzen_string_error_in_debug_locks

Fix `can't modify frozen String` error in `DebugLocks`
This commit is contained in:
Ryuta Kamizono 2017-08-29 15:26:12 +09:00 committed by GitHub
commit 0a1e353c43
2 changed files with 45 additions and 7 deletions

View file

@ -43,7 +43,7 @@ module ActionDispatch
private
def render_details(req)
threads = ActiveSupport::Dependencies.interlock.raw_state do |threads|
threads = ActiveSupport::Dependencies.interlock.raw_state do |raw_threads|
# The Interlock itself comes to a complete halt as long as this block
# is executing. That gives us a more consistent picture of everything,
# but creates a pretty strong Observer Effect.
@ -53,29 +53,29 @@ module ActionDispatch
# strictly diagnostic tool (to be used when something has gone wrong),
# and not for any sort of general monitoring.
threads.each.with_index do |(thread, info), idx|
raw_threads.each.with_index do |(thread, info), idx|
info[:index] = idx
info[:backtrace] = thread.backtrace
end
threads
raw_threads
end
str = threads.map do |thread, info|
if info[:exclusive]
lock_state = "Exclusive"
lock_state = "Exclusive".dup
elsif info[:sharing] > 0
lock_state = "Sharing"
lock_state = "Sharing".dup
lock_state << " x#{info[:sharing]}" if info[:sharing] > 1
else
lock_state = "No lock"
lock_state = "No lock".dup
end
if info[:waiting]
lock_state << " (yielded share)"
end
msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n"
msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n".dup
if info[:sleeper]
msg << " Waiting in #{info[:sleeper]}"

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
require "abstract_unit"
class DebugLocksTest < ActionDispatch::IntegrationTest
setup do
build_app
end
def test_render_threads_status
thread_ready = Concurrent::CountDownLatch.new
test_terminated = Concurrent::CountDownLatch.new
thread = Thread.new do
ActiveSupport::Dependencies.interlock.running do
thread_ready.count_down
test_terminated.wait
end
end
thread_ready.wait
get "/rails/locks"
test_terminated.count_down
assert_match(/Thread.*?Sharing/, @response.body)
ensure
thread.join
end
private
def build_app
@app = self.class.build_app do |middleware|
middleware.use ActionDispatch::DebugLocks
end
end
end