[Zope-dev] ZPatterns, Transactions, _register/_unregister

Phillip J. Eby pje@telecommunity.com
Thu, 17 Aug 2000 13:36:47 -0500


At 11:13 AM 8/14/00 +0200, Bob Pepin wrote:
>Hi,
>I've encountered some weird behaviour in the ZPatterns Transactional class
when
>I was trying to write a User Source for the Login Manager Product.
>
>I'm using Zope 2.2.0 with LoginManager 0.8.7a1 and ZPatterns 0.4.1snap1
>
>The problem is that _unregister seems to be trying to delete the
_v_registered
>attribute of an object that doesn't have it set whenever I return None from
>authenticateUser(). The weird thing is that the object seems to be
>_register()ed and _v_registered appears to be set to 1 in _register(), but
when
>_unregister() is called it has the value 'None' again.
>

Hmmm.  Just a thought, but, does your user source object change itself in
any way during the transaction?  It is possible that it is getting reloaded
from the ZODB during transaction abort, and that would delete the
_v_registered attribute and mess the whole thing up.

Looking at your source code, I see that you are incrementing self.i in your
dbg() method, which is called from other methods that would be active
during the transaction, so this would produce the behavior you're seeing.
Specifically, failing to authorize a user results in an Zope exception
being thrown, causing the transaction to roll back.  As part of the
rollback, the ZODB will invalidate the in-memory state of your UserSource
object (since it was changed during the transaction) and the _v_ attribute
values are lost.  Ironically, you could fix this by changing your debug
code to use a _v_ attribute as well.

Arguably this behavior is an architectural flaw in either Transactional or
the way it is used in DataManager derivatives such as Rack and UserSource.
I'll have to give it some thought, but the cure may be worse than the
disease as I suspect it may require circular references.  :(