This fixes #145 which caused Rails apps to fail booting with errors like the following when configured with Avromatic eager loaded nested models and the zeitwerk classloader:
Attempted to replace existing Avromatic model Emails::Events::EmailRecipient with new model Emails::Events::EmailRecipient as 'emails.email_recipient'. Perhaps 'Emails::Events::EmailRecipient' needs to be eager loaded via the Avromatic eager_load_models setting?
The following sequence of events caused the problem:
Nested models were eager loaded during initialization and registered in the model registry at the end of the Avromatic.configure call
Zeitwerk unloaded all autoloadable classes that were loaded in initializers including these nested models. The model registry still had references to the unloaded classes.
to_prepare callbacks were invoked which triggered loading of nested models again. Logic in this callback did not clear the model registry on the first invocation which resulted in conflicts between the newly loaded nested model classes and the unloaded model registry classes.
The fix is to not force eager loading at the end of Avromatic.configure call since autoloadable constants should not be loaded during application initialization and remove the special first invocation logic from to_prepare to ensure the callback is idempotent. This logic has been tested with both the classic and zeitwerk classloaders.
This fixes #145 which caused Rails apps to fail booting with errors like the following when configured with Avromatic eager loaded nested models and the zeitwerk classloader:
The following sequence of events caused the problem:
Avromatic.configure
callto_prepare
callbacks were invoked which triggered loading of nested models again. Logic in this callback did not clear the model registry on the first invocation which resulted in conflicts between the newly loaded nested model classes and the unloaded model registry classes.The fix is to not force eager loading at the end of
Avromatic.configure
call since autoloadable constants should not be loaded during application initialization and remove the special first invocation logic fromto_prepare
to ensure the callback is idempotent. This logic has been tested with both the classic and zeitwerk classloaders.@will89 - you're prime /cc @erikkessler1