zeitwerk: Uninitialized constant for nested class in sidekiq after code reload with Rails 7 and bootsnap
Hi, I run into issues with sidekiq after making changes with code reload. The project is using Rails 7, Ruby 3.0.3 and Zeitwerk 2.5.1
The relevant directory structure is as follows:
app
├── test
│ ├── a.rb
│ └── b
│ └── c.rb
└── workers
└── test_worker.rb
a.rb
class A
end
c.rb
module B
class C
end
end
Once the application is started everything works fine, both classes are available to rails and sidekiq with no issues. If the code is autoreloaded by making code changes B::C
isn’t available to sidekiq anymore, while both classes are still accesible by rails. Adding an empty module app/test/b.rb
solves the issue, but I shouldn’t have to do that.
I’m not sure if this is a problem with zeitwerk, but it looked like a good place to start since it seems to be some kind of loading issue.
Here is a minimal repro, if needed. https://github.com/Earlopain/zeitwerk-repro. It’s docker, after starting the application will be available under localhost:9000
There’s one page, which prints out A
and B::C
. Loading also calls a sidekiq worker, which only logs A
and B::C
. Again, on first load everything works as expected but after code changes sidekiq cannot find B::C
anymore.
Here's the log for both rails and sidekiq
Initial boot:
22:31:17 puma.1 | Zeitwerk@rails.main: autoload set for ApplicationController, to be loaded from /demo/app/controllers/application_controller.rb
22:31:17 puma.1 | Zeitwerk@rails.main: autoload set for A, to be loaded from /demo/app/test/a.rb
22:31:17 puma.1 | Zeitwerk@rails.main: autoload set for B, to be autovivified from /demo/app/test/b
22:31:17 puma.1 | Zeitwerk@rails.main: autoload set for TestWorker, to be loaded from /demo/app/workers/test_worker.rb
22:31:17 sidekiq.1 | Zeitwerk@rails.main: autoload set for ApplicationController, to be loaded from /demo/app/controllers/application_controller.rb
22:31:17 sidekiq.1 | Zeitwerk@rails.main: autoload set for A, to be loaded from /demo/app/test/a.rb
22:31:17 sidekiq.1 | Zeitwerk@rails.main: autoload set for B, to be autovivified from /demo/app/test/b
22:31:17 sidekiq.1 | Zeitwerk@rails.main: autoload set for TestWorker, to be loaded from /demo/app/workers/test_worker.rb
First request:
22:31:19 puma.1 | Zeitwerk@rails.main: constant ApplicationController loaded from file /demo/app/controllers/application_controller.rb
22:31:19 puma.1 | Zeitwerk@rails.main: constant A loaded from file /demo/app/test/a.rb
22:31:19 puma.1 | Zeitwerk@rails.main: module B autovivified from directory /demo/app/test/b
22:31:19 puma.1 | Zeitwerk@rails.main: autoload set for B::C, to be loaded from /demo/app/test/b/c.rb
22:31:19 puma.1 | Zeitwerk@rails.main: constant B::C loaded from file /demo/app/test/b/c.rb
22:31:19 puma.1 | Zeitwerk@rails.main: constant TestWorker loaded from file /demo/app/workers/test_worker.rb
22:31:19 sidekiq.1 | Zeitwerk@rails.main: constant TestWorker loaded from file /demo/app/workers/test_worker.rb
22:31:19 sidekiq.1 | Zeitwerk@rails.main: constant A loaded from file /demo/app/test/a.rb
22:31:19 sidekiq.1 | Zeitwerk@rails.main: module B autovivified from directory /demo/app/test/b
22:31:19 sidekiq.1 | Zeitwerk@rails.main: autoload set for B::C, to be loaded from /demo/app/test/b/c.rb
22:31:19 sidekiq.1 | Zeitwerk@rails.main: constant B::C loaded from file /demo/app/test/b/c.rb
Code changed, second request:
22:34:24 puma.1 | Zeitwerk@rails.main: ApplicationController unloaded
22:34:24 puma.1 | Zeitwerk@rails.main: A unloaded
22:34:24 puma.1 | Zeitwerk@rails.main: B unloaded
22:34:24 puma.1 | Zeitwerk@rails.main: B::C unloaded
22:34:24 puma.1 | Zeitwerk@rails.main: TestWorker unloaded
22:34:24 puma.1 | Zeitwerk@rails.main: autoload set for ApplicationController, to be loaded from /demo/app/controllers/application_controller.rb
22:34:24 puma.1 | Zeitwerk@rails.main: autoload set for A, to be loaded from /demo/app/test/a.rb
22:34:24 puma.1 | Zeitwerk@rails.main: autoload set for B, to be autovivified from /demo/app/test/b
22:34:24 puma.1 | Zeitwerk@rails.main: autoload set for TestWorker, to be loaded from /demo/app/workers/test_worker.rb
22:34:24 puma.1 | Zeitwerk@rails.main: constant ApplicationController loaded from file /demo/app/controllers/application_controller.rb
22:34:24 puma.1 | Zeitwerk@rails.main: constant A loaded from file /demo/app/test/a.rb
22:34:24 puma.1 | Zeitwerk@rails.main: module B autovivified from directory /demo/app/test/b
22:34:24 puma.1 | Zeitwerk@rails.main: autoload set for B::C, to be loaded from /demo/app/test/b/c.rb
22:34:24 puma.1 | Zeitwerk@rails.main: constant B::C loaded from file /demo/app/test/b/c.rb
22:34:24 puma.1 | Zeitwerk@rails.main: constant TestWorker loaded from file /demo/app/workers/test_worker.rb
22:34:24 sidekiq.1 | Zeitwerk@rails.main: autoload for ApplicationController removed
22:34:24 sidekiq.1 | Zeitwerk@rails.main: TestWorker unloaded
22:34:24 sidekiq.1 | Zeitwerk@rails.main: A unloaded
22:34:24 sidekiq.1 | Zeitwerk@rails.main: B unloaded
22:34:24 sidekiq.1 | Zeitwerk@rails.main: B::C unloaded
22:34:24 sidekiq.1 | Zeitwerk@rails.main: autoload set for ApplicationController, to be loaded from /demo/app/controllers/application_controller.rb
22:34:24 sidekiq.1 | Zeitwerk@rails.main: autoload set for A, to be loaded from /demo/app/test/a.rb
22:34:24 sidekiq.1 | Zeitwerk@rails.main: autoload set for B, to be autovivified from /demo/app/test/b
22:34:24 sidekiq.1 | Zeitwerk@rails.main: autoload set for TestWorker, to be loaded from /demo/app/workers/test_worker.rb
22:34:24 sidekiq.1 | Zeitwerk@rails.main: constant TestWorker loaded from file /demo/app/workers/test_worker.rb
22:34:24 sidekiq.1 | Zeitwerk@rails.main: constant A loaded from file /demo/app/test/a.rb
After making changes sidekiq unloads B::C
but does not reload it.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 24 (20 by maintainers)
Links to this issue
Commits related to this issue
- Tmp disable of bootsnap asper https://github.com/fxn/zeitwerk/issues/198#issuecomment-1000997860 — committed to Earlopain/reverser by Earlopain 3 years ago
- Revert "Store directories in $LOADED_FEATURES" This change resulted in a performance regression, that was particularly dramatic in Ruby Ruby 3.1. We'll address #198 in a different way. This reverts... — committed to fxn/zeitwerk by fxn 3 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- LoadedFeaturesIndex#register: Ignore absolute paths entirely Fix: https://github.com/Shopify/bootsnap/issues/383 Ref: https://github.com/fxn/zeitwerk/issues/198 The loaded feature index goal is to p... — committed to Shopify/bootsnap by byroot 2 years ago
- devel/ruby-railties70: 7.0.1 (2021-01-06) * Prevent duplicate entries in plugin Gemfile. Jonathan Hefner * Fix asset pipeline errors for plugin dummy apps. Jonathan Hefner * Fix generated rou... — committed to NetBSD/pkgsrc by deleted user 2 years ago
- Pullup ticket #6594 - requested by taca www/ruby-rails70: security fix Revisions pulled up: - databases/ruby-activerecord70/distinfo 1.2-1.3 - devel/ruby-activejob70/distinfo ... — committed to NetBSD/pkgsrc by bsiegert 2 years ago
- Pullup ticket #6594 - requested by taca www/ruby-rails70: security fix Revisions pulled up: - databases/ruby-activerecord70/distinfo 1.2-1.3 - devel/ruby-activejob70/distinfo ... — committed to NetBSD/pkgsrc by bsiegert 2 years ago
First, let me congratulate you on this extremely good bug report. Terrific.
I have been able to reproduce and the behavior is puzzling, I’ll dig into it.
I will give the revised fix a try tomorrow.