We figured out, that ActiveJob Inline might lead to autoloading problems in development. The result was an exception when running an import script, which delivers async mails.
A copy of XXX has been removed from the module tree but is still active! (ArgumentError)
Our fix was to use .deliver_now
and not .deliver_later
(this is not a general fix, but it was okey for us). Below there are some debug hints which helped us to locate the problem:
- We placed a pry debugger in ActiveSupport#clear Show archive.org snapshot (this is the part where classes are loaded and unloaded) and stopped spring
- We ran the script and waited until the debugger was triggered
- In the debugger we looked up the caller by first running
raise
, thenwtf????????????
in pry (wtf
is a pry command, the more?
you add, the longer the backtrace becomes)
The useful lines looked like this in the backtrace:
59: /home/user/.rvm/gems/ruby-2.5.1/gems/activejob-5.2.1/lib/active_job/execution.rb:22:in `execute'
60: /home/user/.rvm/gems/ruby-2.5.1/gems/activejob-5.2.1/lib/active_job/queue_adapters/inline_adapter.rb:15:in `enqueue'
We didn't dig deeper into the root cause at this point, but it already helped us to understand which part of the importer caused the exception.
Beside this it was also helpful to print to the console when the module tree was cleared (puts in ActiveSupport#clear Show archive.org snapshot ) and which dependencies where added (puts in ActiveSupport#load_missing_constant Show archive.org snapshot ).
Here is a simple example output:
Load the constant named ApplicationRecord which is missing from Object
Load the constant named User which is missing from Object
Load the constant named User::Importer which is missing from User
Clear the dependencies
Load the constant named ApplicationRecord which is missing from Object
Load the constant named User which is missing from Object
Load the constant named User::Importer which is missing from User
=> A copy of User has been removed from the module tree but is still active! (ArgumentError)
We used this to check if the constant claimed by the exception was loaded before someone threw it away.
If you don't use .deliver_later
in your application code and see the error above, you might want to look at Fixing "A copy of Klass has been removed from the module tree but is still active".