Thanks for the quick response to this as usual. See me responses below. On Fri, Mar 4, 2011 at 7:32 AM, Michael Bayer <mike...@zzzcomputing.com>wrote:
> > On Mar 4, 2011, at 2:58 AM, Lenza McElrath wrote: > > Hello! I'm iterating over a session to look at all the objects: > > for obj in session: > do_something_cool(obj) > > Yesterday this caused what looks like a deadlock in SQLAlchemy code. Here > is the stack I grabbed using gdb: > > 1. /python2.5/sqlalchemy/orm/session.py:1353 (Session.__iter__) > 2. /python2.5/sqlalchemy/orm/identity.py:184 (WeakInstanceDict.values) > 3. /python2.5/sqlalchemy/orm/identity.py:188 ( > WeakInstanceDict.itervalues) ** self._remove_mutex.acquire() > 4. /python2.5/sqlalchemy/orm/state.py:501 ( > MutableAttrInstanceState.__resurrect) > 5. /python2.5/sqlalchemy/orm/attributes.py:925 (Events.run) > 6. /python2.5/sqlalchemy/orm/mapper.py:2424 (_event_on_resurrect) > 7. /python2.5/sqlalchemy/util.py:953 (OrderedSet.__iter__) > 8. /python2.5/sqlalchemy/orm/state.py:477 ( > MutableAttrInstanceState._cleanup) > 9. /python2.5/sqlalchemy/orm/identity.py:139A (WeakInstanceDict.remove)** > self._remove_mutex.acquire > () > > I'm running SQLAlchemy 0.6.5. Is this a known issue or am I doing > something wrong? > > > I've never seen that before. A reentrant mutex would fix this but I > really hate to use those as they have a big performance hit and thats a very > critical section. Its true this is also related to "mutable" attributes > which is something I'd eventually like to remove entirely - they are pending > deprecation in 0.7. Is this issue consistently reproducible and can you > send me a test case ? This would be very high priority. > > Not sure if this helps but one of the triggers there is you have an object > that has "mutable" attributes on it, which is dirty, and has been garbage > collected. The "state" hangs around in the Session and when accessed > resurrects itself. At that point, it seems like some other object that was > also garbage collected starts doing the same thing before the process for > object #1 can complete, its not clear why that would happen here, thats the > point at which I'd want to pdb around to see what that's about. > This issue was in-consistently reproducible, but it is in a production system where a workaround has been applied, so now it is not-so-reproducible (hopefully). Every object has mutable attributes on it, so it is not surprising that there would be a dirty one in the session. Here is the do_something_cool function in case it provides some insight: def do_something_cool(obj, do_copy=False): for obj in session: if do_copy: ret_obj = copy.deepcopy(obj) else: ret_obj = obj ret_obj._has_been_flagged = True return ret_obj I believe do_copy should be False in this situation, but given the weirdness I would exclude the possibility that it is True. > > > On a somewhat related note, am experiencing the issue where lots of objects > in a session significantly reduces performance. It appears I am > experiencing the penalty for using MutableTypes on objects described here: > http://readthedocs.org/docs/sqlalchemy/en/latest/core/types.html#base-type-api. > The doc states: > > In order to detect changes, the ORM must create a copy of the value when it > is first accessed, so that changes to the current value can be compared > against the “clean” database-loaded value. Additionally, when the ORM checks > to see if any data requires flushing, it must scan through all instances in > the session which are known to have “mutable” attributes and compare the > current value of each one to its “clean” value. > > It doesn't seem like I should have to pay this penalty because with my type > I actually know when any updates occur. The type just supports > models.mutable_value.update(data). Is there a way to notify the > model/session that the value has been updated when someone calls update, so > the full scan of all instances is not needed? Do I need to rewrite the > update function to translate models.mutable_value.update(data) to actually > generate models.mutable_value = new_mutable_value or is there a better way > to do this? > > > very easy. Upgrade to 0.7. All has been resolved there, to support > in-place mutation detection you use the techniques described at > http://www.sqlalchemy.org/docs/07/orm/extensions/mutable.html . > > Of course you'd be beta testing something I'm not sure anyone is using yet. > Hopefully no deadlocks though ! :) (but again, I'd love to fix that > deadlock, I'll be looking at that today and a test case would be v. helpful) > So there is no way to accomplish this in 0.6? I was looking at doing it the way I describe above, but it is not trivial to figure out which model/session a value is attached to. And I guess it is theoretically possible that a value could be connected to two models/sessions. Definitely scared of moving to an untested code... but looks like there are lots of improvements in 0.7 that might make it worth it... -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.