[ZODB-Dev] zodb wants to import my module?
Tim Peters
tim at zope.com
Thu Nov 11 11:20:40 EST 2004
[Jeremy Hylton]
> It should also work fine if you don't have the code on the server. ZEO
> should raise that exception for a class exactly once in the process's
> lifetime. It's trying to discover if the class has a conflict resolution
> method that the server should run.
I expect you're thinking here of tryToResolveConflict()'s ``_unresolvable``
cache of classes lacking conflict resolution methods, and are also thinking
here that a *log* message about "Unable to load class" is produced at most
once per class.
But none of that's relevant here: the problem is in
ConflictError.__init__():
if serial != cached_tid:
rdata = self.tryToResolveConflict(oid, cached_tid,
serial, data)
if rdata is None:
raise POSException.ConflictError(
oid=oid, serials=(cached_tid, serial),
data=data) # HERE
else:
data = rdata
*Every* time we try to raise ConflictError for an object of an application
class, where the application code isn't present, the exception's constructor
tries to load the first half of the ``data`` pickle, and so gets an
ImportError every time. This code was new in 3.3, and has the consequence
Chris reported: the ZEO client (re)raises the ImportError the server got
while trying to build a ConflictError exception. tryToResolveConflict's
cache's only effect here is, in effect, to raise ImportError a little
quicker after the first time it's raised <wink>.
This is fixed on 3.3 branch now, and will be fixed soon on the trunk.
> (We've talked many times about changing the mechanism ZEO uses so
> that you can explicitly configure callables to run on conflicts for a
> particuar class. There's no good reason to make them methods, and it
> causes some problems.)
I look forward to your patch <wink>.
> It can occasionally be bad to have client code on the server. The
> problem is that the client code actually gets executed :-). If the
> client code expects to be running inside of Zope, it can actually start
> to bring up Zope within the ZEO server. That's very bad. In general, if
> the code has side-effects at import time, you want to think carefully
> about whether you want those side-effects to occur on your ZEO server.
"The fix" here consisted of having the ConflictError constructor use
get_pickle_metadata() to get the class path instead of actually loading the
first half of the ZODB pickle. God only knows if get_pickle_metadata() does
a right thing in all cases, but there's no other way to proceed. There are
no known cases now in which get_pickle_metadata() will try to import modules
or classes (one case in which it did has been repaired since you were here).
More information about the ZODB-Dev
mailing list