Code-reloading issues in stale classes

We have stale classes in memory when code-reloading is enabled because we reference these classes in non-autoloaded classes.

A prime example of this is middleware (Rack / Sidekiq) because these are held in memory. And then, when any code is changed and all autoloaded classes are unloaded, these would be stale.

Normally, these would work fine and these references would just not pick up any changes made to the classes. But there is a problem when this stale class tries to autoload another class.

You will get an error like:

     ArgumentError:
       A copy of Gitlab::SidekiqMiddleware::AdminMode::Client has been removed from the module tree but is still active!
     # ./lib/gitlab/sidekiq_middleware/admin_mode/client.rb:11:in `call'
     # ./lib/gitlab/sidekiq_status/client_middleware.rb:10:in `call'

In this specific case, this class is trying to autoload Feature and Gitlab::SidekiqMiddleware::AdminMode::Client.const_missing is triggered which then raises this exception because the current module is stale.

A workaround is to use a fully qualified class name ::Feature so that Object.const_missing will be triggered.

https://stackoverflow.com/a/29710188 has more details

When we switched to Zeitwerk we also saw a similar problem although the exception is different. Even though Zeitwerk doesn't use const_missing, there seems to be a similar problem with autoloading in these stale classes.

An example report is described below:

Zeitwerk seems to have some quirks on how it handles name lookups in ruby. We had to revert Zeitwerk support !27539 (merged) because, after a code-reload is triggered, we were having the following error preventing the execution flow to continue:

Unexpected error while processing request: uninitialized constant Gitlab::Metrics::RequestsRackMiddleware::RequestsRackMiddleware

the problem is that zeitwerk is duplicating the name of the class: RequestsRackMiddleware when we try to call it to reach the a class method in: http://gitlab.com/gitlab-org/gitlab/blob/70e9450ecaf97c0b6a934f71ef6d90511966377e/lib/gitlab/metrics/requests_rack_middleware.rb#L47-57

A way to fix this and other related issues is to use self.class instead of naming the class. Another alternative is to use the full namespace prefix with :: :

::Gitlab::Metrics::RequestsRackMiddleware
Edited by Heinrich Lee Yu