{"action":"created","issue":{"url":"https://api.github.com/repos/rails/rails/issues/25344","repository_url":"https://api.github.com/repos/rails/rails","labels_url":"https://api.github.com/repos/rails/rails/issues/25344/labels{/name}","comments_url":"https://api.github.com/repos/rails/rails/issues/25344/comments","events_url":"https://api.github.com/repos/rails/rails/issues/25344/events","html_url":"https://github.com/rails/rails/pull/25344","id":159605104,"number":25344,"title":"ActionDispatch::DebugLocks","user":{"login":"matthewd","id":1034,"avatar_url":"https://avatars.githubusercontent.com/u/1034?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewd","html_url":"https://github.com/matthewd","followers_url":"https://api.github.com/users/matthewd/followers","following_url":"https://api.github.com/users/matthewd/following{/other_user}","gists_url":"https://api.github.com/users/matthewd/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewd/subscriptions","organizations_url":"https://api.github.com/users/matthewd/orgs","repos_url":"https://api.github.com/users/matthewd/repos","events_url":"https://api.github.com/users/matthewd/events{/privacy}","received_events_url":"https://api.github.com/users/matthewd/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rails/rails/labels/actionpack","name":"actionpack","color":"FFF700"},{"url":"https://api.github.com/repos/rails/rails/labels/needs%20feedback","name":"needs feedback","color":"ededed"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/rails/rails/milestones/53","html_url":"https://github.com/rails/rails/milestones/5.0.1","labels_url":"https://api.github.com/repos/rails/rails/milestones/53/labels","id":1730927,"number":53,"title":"5.0.1","description":null,"creator":{"login":"jeremy","id":199,"avatar_url":"https://avatars.githubusercontent.com/u/199?v=3","gravatar_id":"","url":"https://api.github.com/users/jeremy","html_url":"https://github.com/jeremy","followers_url":"https://api.github.com/users/jeremy/followers","following_url":"https://api.github.com/users/jeremy/following{/other_user}","gists_url":"https://api.github.com/users/jeremy/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremy/subscriptions","organizations_url":"https://api.github.com/users/jeremy/orgs","repos_url":"https://api.github.com/users/jeremy/repos","events_url":"https://api.github.com/users/jeremy/events{/privacy}","received_events_url":"https://api.github.com/users/jeremy/received_events","type":"User","site_admin":false},"open_issues":18,"closed_issues":33,"state":"open","created_at":"2016-04-26T02:02:53Z","updated_at":"2016-09-27T21:20:38Z","due_on":null,"closed_at":null},"comments":6,"created_at":"2016-06-10T10:24:40Z","updated_at":"2016-09-28T05:29:19Z","closed_at":"2016-07-01T21:17:57Z","pull_request":{"url":"https://api.github.com/repos/rails/rails/pulls/25344","html_url":"https://github.com/rails/rails/pull/25344","diff_url":"https://github.com/rails/rails/pull/25344.diff","patch_url":"https://github.com/rails/rails/pull/25344.patch"},"body":"While looking at https://github.com/rails/rails/issues/25117, I was again struck by how uninformative \"hang on all new requests\" is as a diagnostic output.\r\n\r\nWe'd thrown around the idea of checking thread statuses and guessing when things might be stuck, but I'm still nervous that we'd trip on too many legitimately slow operations.\r\n\r\nInstead, I propose this middleware.\r\n\r\nIf your application appears to be experiencing a deadlock, you can insert this, then go to `/rails/locks`, to see output like:\r\n\r\n```\r\nThread 0 [0x3fda9bc30cfc sleep]  No interlock (yielded share)\r\n  Waiting in start_exclusive to \"load\"\r\n  may be pre-empted for: \"load\"\r\n  blocked by: 1\r\n\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:111:in `sleep'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:111:in `wait'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:111:in `wait'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:123:in `wait_while'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:220:in `wait_for'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:82:in `block (2 levels) in start_exclusive'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:186:in `yield_shares'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:81:in `block in start_exclusive'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:76:in `start_exclusive'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/concurrency/share_lock.rb:148:in `exclusive'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies/interlock.rb:11:in `loading'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:37:in `load_interlock'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:358:in `require_or_load'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:511:in `load_missing_constant'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:203:in `const_missing'\r\n/Users/matthew/tmp/puma_channel_problem/app/channels/first_channel.rb:3:in `<top (required)>'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:293:in `require'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:293:in `block in require'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:259:in `load_dependency'\r\n/Users/matthew/src/rails/activesupport/lib/active_support/dependencies.rb:293:in `require'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/base.rb:74:in `block (2 levels) in channel_classes'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/base.rb:74:in `each'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/base.rb:74:in `block in channel_classes'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/base.rb:72:in `channel_classes'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/subscriptions.rb:29:in `add'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/subscriptions.rb:15:in `execute_command'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/base.rb:88:in `dispatch_websocket_message'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/worker.rb:54:in `block in invoke'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/worker.rb:39:in `block in work'\r\n[snip]\r\n\r\n\r\n---\r\n\r\n\r\nThread 1 [0x3fda9a3cf460 sleep]  Sharing\r\n  blocking: 0\r\n\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:187:in `lock'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:187:in `mon_enter'\r\n/Users/matthew/.rbenv/versions/2.3.0/lib/ruby/2.3.0/monitor.rb:212:in `mon_synchronize'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/base.rb:72:in `channel_classes'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/subscriptions.rb:29:in `add'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/subscriptions.rb:15:in `execute_command'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/connection/base.rb:88:in `dispatch_websocket_message'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/worker.rb:54:in `block in invoke'\r\n/Users/matthew/src/rails/actioncable/lib/action_cable/server/worker.rb:39:in `block in work'\r\n[snip]\r\n```\r\n\r\nNaturally, we're able to provide lots of information about the actual interlock state (some of which is derived from duplicated logic for now, but that could be refactored later), but we can't offer much about whatever \"other\" lock is involved. However, the above example demonstrates that the backtraces may often be sufficient."},"comment":{"url":"https://api.github.com/repos/rails/rails/issues/comments/250075256","html_url":"https://github.com/rails/rails/pull/25344#issuecomment-250075256","issue_url":"https://api.github.com/repos/rails/rails/issues/25344","id":250075256,"user":{"login":"connorshea","id":2977353,"avatar_url":"https://avatars.githubusercontent.com/u/2977353?v=3","gravatar_id":"","url":"https://api.github.com/users/connorshea","html_url":"https://github.com/connorshea","followers_url":"https://api.github.com/users/connorshea/followers","following_url":"https://api.github.com/users/connorshea/following{/other_user}","gists_url":"https://api.github.com/users/connorshea/gists{/gist_id}","starred_url":"https://api.github.com/users/connorshea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/connorshea/subscriptions","organizations_url":"https://api.github.com/users/connorshea/orgs","repos_url":"https://api.github.com/users/connorshea/repos","events_url":"https://api.github.com/users/connorshea/events{/privacy}","received_events_url":"https://api.github.com/users/connorshea/received_events","type":"User","site_admin":false},"created_at":"2016-09-28T05:29:19Z","updated_at":"2016-09-28T05:29:19Z","body":"@matthewd why no Changelog entry? This seems super useful!"}}
{"actor":{"display_login":"connorshea"}}