I diagnosed the following issue as part of [1], but it has since come up again as part of [2].
== The issue: ==
Whenever an AR::Base instance is persisted between requests with cache_classes disabled, Dispatcher#reset_application! will go through all its subclasses and remove all its instance methods and instance variables (those on the instance of Class not on instances of AR::Base, it's all very confusing!).
This was intended to fix a memory leak [3], and had a test associated with it. The test is now long gone, and my efforts at re-adding it failed because I never got it to pass, with or without the class stripping.
== The effect: ==
The example app by David Rice [4] will explode with error [5] after 2 page loads.
This app saves an AR model to a constant at startup... then expects it to work after a reload!.
After a reload the model gets very confused, as its class has all its class_inheritable_attributes stripped.
It expects an array to be dangling off the end of #skip_time_zone_conversion_for_attributes, but instead it finds nil.
This sucks.
== What should happen (IMHO): ==
Removing the references to classes in @@subclasses should be enough to allow garbage collection to do the good stuff when the relevant constants (that refer to the classes) are removed.
This way, any objects that are still referencing those classes (you know, like when they are an instance of them), can still operate without unnecessary loss of organs.
== The patch: ==
The attached patch, rebased especially for the occasion, stops AR from behaving in this odd way, and seems to pass the existing test pack.
== The questions: ==
Does anyone have a good reason why these lines should stay?
Can anyone create a failing test case? (preferably one that passes before the patch is applied
Does anyone remember why the code is there?
Thanks in advance for any thoughts / input / other. - Tom
p.s. I had to revert my local rails back to 55707da1a1481, as 8adb79b9b598 onwards clashed with my MySQL. Tests passed at that point though.
prevent_class_method_and_variable_nukeing_on_AR_reset_subclasses.diff (1.07 KB)