This project is archived and is in readonly mode.
define_attribute_methods race leads to method missing exception while creating objects conccurently
Reported by lcars | September 16th, 2010 @ 11:10 AM
Hi, we are experiencing random 'undefined method' errors while creating objects in an heavily threaded environment, here's an example:
caught exception in
vendor/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/attribute_method
s.rb:255:in method_missing'
undefined method uuid=' for #<OurObject:0xdef731>
... etc etc
with random I mean very rarely and apparently only once after application startup. In OurObject 'uuid' is the primary key. The code which leads to the exception is the following:
o = new(params)
o.uuid = params['uuid']
We think this might be a race in how method_missing override (in attribute_methods.rb) checks if all attribute methods have been defined before invoking super on ruby's own method_missing.
If we check the define_attribute_methods we see the following:
def define_attribute_methods
return if generated_methods?
...
end
This means that define_attribute_methods returns if any number (even just one out of hunders ) of methods have been added to the @generated_methods instance set for the object columns.
Considering this along with the fact that these are all class methods without mutex protection, is it possible in an heavily threaded environment for two objects of the same class, in separate threads, to invoke define_attribute_methods at the same time making one of the two bailing out prematurely because generated_methods? was satisfied that at least one attribute method was set (by the other thread) ?
This would lead to method_missing skipping this conditional:
if !self.class.generated_methods?
self.class.define_attribute_methods
if self.class.generated_methods.include?(method_name)
return self.send(method_id, *args, &block)
end
end
...and eventually hitting the super which would cause the exception.
Unfortunately I don't have time to create a test for this.
Thanks
Comments and changes to this ticket
-
Santiago Pastorino February 2nd, 2011 @ 04:31 PM
- State changed from new to open
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino February 2nd, 2011 @ 04:31 PM
- State changed from open to stale
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>