rails: Sidekiq hangs using Rails 6 app with "classic" autoloader
Originally discussed on https://github.com/mperham/sidekiq/issues/4216 . This appears to be caused by a deadlock within actiontext.
Steps to reproduce
- Create a new rails app using Rails 6.0.0.rc2
- Add Sidekiq and create some jobs (I used the instructions here https://github.com/mperham/sidekiq/wiki/Getting-Started#rails)
- Run
bundle exec sidekiq
- Watch as it completes the jobs
- Switch to the classic autoloader (and do a
spring stop
) - Create more jobs
- Run
bundle exec sidekiq
- Watch as it starts jobs, but never completes any.
Here is a test app based on the instructions above: https://github.com/langsharpe/test_sidekiq_activetext
Here is a gist of the output of the process after sending the TTIN signal https://gist.githubusercontent.com/langsharpe/8ca50bca283f863e09c226b0b88a3f57/raw/f8d6343fe2e388b6b2a16988dd281b29c57c332f/Sidekiq.log
Our use case is an existing app we upgraded to Rails 6, but is not Zeitwerk compatible (yet). The problem only occurs when code is autoloaded. It doesn’t occur when code is eager loaded (e.g. in production mode)
Expected behavior
Jobs should complete when using the classic autoloader.
Actual behavior
Jobs start, but never finish.
System configuration
Rails version: 6.0.0.rc2 Ruby version: 2.6.2p47 (2019-03-13 revision 67232) [x86_64-darwin18]
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 10
- Comments: 21 (13 by maintainers)
Commits related to this issue
- Bugfix: Sidekiq queues getting stuck [#411] ref: https://github.com/rails/rails/issues/36810 closes: #411 — committed to chatwoot/chatwoot by sojan-official 4 years ago
- Fix sidekiq version 6 issue with classic autoloader Related issue found here https://github.com/rails/rails/issues/36810 — committed to ministryofjustice/laa-apply-for-legal-aid by Obsiye 4 years ago
Yes. Our workaround in development is to use a concurrency of 1.
I managed to capture a backtrace of all the threads (using method described in http://le-huy.blogspot.com/2012/04/dump-backtrace-of-all-threads-in-ruby.html)
Lots of noise here, but looking at
actiontext-6.0.2.1/lib/action_text/engine.rb:46
this might lead to the issue:When I blindly comment out that line, it works.
Initially it looked like my problem was fixed, but unfortunately setting the concurrency to 1 did not fix it. The bug just takes a bit longer to show up.
I am seeing this bug, every time I make a change in my code Sidekiq freezes and won’t proces any jobs until I restart the proces. Setting the concurrency to 1 seems to fix the problem.
I also commented this in the sidekiq github but:
Hi everyone - I’ve had similar situations and found this thread. I, like others potentially, cheated while upgrading and as-of 6.0 I began to see jobs stuck in busy as well. Moving to “load_defaults 6.0” seemed to work for me until I removed my old new_framework_defaults.rb (which I didn’t think I needed anymore). Then the problem reappeared. Restored the file and traced to see what might have exposed this for me.
In my case I have it narrowed down to: ActiveSupport.to_time_preserves_timezone = false
If the above is set, I see no hangs. If I comment this out or revert to the default true as-of 5.0, then I see the jobs stuck in the busy state again.
Perhaps I have something else wrongly or inconsistently configured - but wanted to share this in case it sheds any light on what might be the root cause and how to resolve it.
ruby 2.7.0 rails 6.0.2.2 sidekiq 6.0.6