[Zope] Zope pretends to receive and send XMLRPC data,
but strace sees nothing ! (fwd)
yacine chaouche
yacinechaouche at gmail.com
Thu Jan 25 09:48:53 EST 2007
>Is _p_resolveConflict method of Inceraser executed at all?
>I wonder if traceback you see in console is from the
>code you added:
>traceback.print_exc(file=stdin)
>
>or it is always shown when there is a conflict error.
<code>
def _p_resolveConflict(self, old, state1, state2):
print "called the _p_resolveConflict of the Increaser object",self
try:
number = max(old,state1,state2)
except Exception,msg:
import traceback
traceback.print_exc(file=sys.stdin)
return max(old, state1, state2)
</code>
Yes, The method was not called. However, the traceback was indeed printed by
the print_exc, since there were no tracebacks before I added this line. In
fact, as Gabriel Genellina said :
>That might provoke a ConflictError, forcing a
>transaction abort and the request to be re-tried (up to three times,
>silently, then it goes logged).
as well as Pascal Peregrina:
>In general, retry is called when a ZODB Conflict Error has happened.
>If I remember well, Zope will silently retry 3 times, and then actually
>return an error page showing the Conflict Error.
as the documentation says
http://www.zope.org/Documentation/Books/ZDG/current/ObjectPublishing.stx :
"If an unhandled exception is raised during the publishing process, Zope
aborts the transaction. As detailed in Chapter 4. Zope handles
ConflictErrors by re-trying the request up to three times. This is done with
the zpublisher_exception_hook."
Thus, I don't think that the traceback is always shown when there's a
conflict error.
So I decided to look into the file suggested by Maciej Wisniowski :
>You may take a look at lib/python/ZODB/ConflictResolution.py
>method: tryToResolveConflict. There is a call to _p_resolveConflict.
and edited it like this :
<code>
def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
committedData=''):
# class_tuple, old, committed, newstate = ('',''), 0, 0, 0
print "in ConflictResolution.py, called the tryToResolveConflict method
with arguments :"
print
"self",self,"oid",oid.__repr__(),"committedSerial",committedSerial.__repr__(),"oldSerial",oldSerial.__repr__(),"newpickle",newpickle.__repr__(),"committedData",committedData.__repr__()
try:
prfactory = PersistentReferenceFactory()
file = StringIO(newpickle)
unpickler = Unpickler(file)
unpickler.find_global = find_global
unpickler.persistent_load = prfactory.persistent_load
meta = unpickler.load()
if isinstance(meta, tuple):
klass = meta[0]
newargs = meta[1] or ()
if isinstance(klass, tuple):
klass = find_global(*klass)
else:
klass = meta
newargs = ()
if klass in _unresolvable:
print "klass",klass.__repr__,"is unresolvable"
return None
newstate = unpickler.load()
inst = klass.__new__(klass, *newargs)
try:
resolve = inst._p_resolveConflict
except AttributeError:
print inst.__repr__,"has no _p_resolveConflict method"
_unresolvable[klass] = 1
return None
old = state(self, oid, oldSerial, prfactory)
committed = state(self, oid, committedSerial, prfactory,
committedData)
resolved = resolve(old, committed, newstate)
file = StringIO()
pickler = Pickler(file,1)
pickler.persistent_id = persistent_id
pickler.dump(meta)
pickler.dump(resolved)
print "everything's ok"
return file.getvalue(1)
except (ConflictError, BadClassName):
print "ConflictError during conflict resolution in tryToResolveConflict,
ConflictResolution.py"
import traceback
import sys
traceback.print_exc(file = sys.stdout)
return None
except:
print "Exception raised in in tryToResolveConflict,
ConflictResolution.py"
import traceback
import sys
traceback.print_exc(file=sys.stdout)
# If anything else went wrong, catch it here and avoid passing an
# arbitrary exception back to the client. The error here will mask
# the original ConflictError. A client can recover from a
# ConflictError, but not necessarily from other errors. But log
# the error so that any problems can be fixed.
logger.error("Unexpected error", exc_info=True)
return None
</code>
Now let's see what's going on in the console :
<console>
in ConflictResolution.py, called the tryToResolveConflict method with
arguments :
self <tempstorage.TemporaryStorage.TemporaryStorage instance at 0x43fb6aac>
oid '\x00\x00\x00\x00\x00\x00\x00\t' committedSerial
'\x03k#\x93\x1d\xff\xf5\x11' oldSerial '\x03k#\x91^t\xf1D' newpickle '(
cProducts.Transience.Transience\nIncreaser\nq\x01)tq\x02.J\x88\xa6\xb8E.'
committedData ''
ConflictError during conflict resolution in tryToResolveConflict,
ConflictResolution.py
Traceback (most recent call last):
File "/opt/aef/Zope-2.9.0/lib/python/ZODB/ConflictResolution.py", line
126, in tryToResolveConflict
old = state(self, oid, oldSerial, prfactory)
File "/opt/aef/Zope-2.9.0/lib/python/ZODB/ConflictResolution.py", line 53,
in state
p = p or self.loadSerial(oid, serial)
File "/opt/aef/Zope-2.9.0//lib/python/tempstorage/TemporaryStorage.py",
line 148, in loadSerial
raise POSException.ConflictError(oid=oid)
ConflictError: database conflict error (oid 0x09)
<comment> the exception is raised up to the publish function, since it has
not been catched, and I added up a code to print traceback in the publish
function so here it is </comment>
exception raised in the publish module, in function publish
Traceback (most recent call last):
File "/opt/aef/Zope-2.9.0/lib/python/ZPublisher/Publish.py", line 119, in
publish
transactions_manager.commit()
File "/opt/aef/Zope-2.9.0//lib/python/Zope2/App/startup.py", line 234, in
commit
transaction.commit()
File "/opt/aef/Zope-2.9.0//lib/python/transaction/_manager.py", line 96,
in commit
return self.get().commit(sub, deprecation_wng=False)
File "/opt/aef/Zope-2.9.0//lib/python/transaction/_transaction.py", line
380, in commit
self._saveCommitishError() # This raises!
File "/opt/aef/Zope-2.9.0//lib/python/transaction/_transaction.py", line
378, in commit
self._commitResources()
File "/opt/aef/Zope-2.9.0//lib/python/transaction/_transaction.py", line
433, in _commitResources
rm.commit(self)
File "/opt/aef/Zope-2.9.0//lib/python/ZODB/Connection.py", line 484, in
commit
self._commit(transaction)
File "/opt/aef/Zope-2.9.0//lib/python/ZODB/Connection.py", line 526, in
_commit
self._store_objects(ObjectWriter(obj), transaction)
File "/opt/aef/Zope-2.9.0//lib/python/ZODB/Connection.py", line 554, in
_store_objects
s = self._storage.store(oid, serial, p, self._version, transaction)
File "/opt/aef/Zope-2.9.0//lib/python/tempstorage/TemporaryStorage.py",
line 200, in store
data=data)
ConflictError: database conflict error (oid 0x09, class
Products.Transience.Transience.Increaser, serial this txn started with
0x036b23915e74f144 2007-01-25 13:05:22.138314, serial currently committed
0x036b23931dfff511 2007-01-25 13:07:07.031211)
</console>
The exception is raised, as the traceback says, in File
"/opt/aef/Zope-2.9.0//lib/python/tempstorage/TemporaryStorage.py",
line 148, in loadSerial
raise POSException.ConflictError(oid=oid)
Is it normal that the oid, as an argument to tryToResloveConflict, was
"\x00\x00\x00\x00\x00\x00\x00\t" then became 0x09 when the exception was
raised ?
here's the loadSerial code :
<code>
def loadSerial(self, oid, serial, marker=[]):
""" this is only useful to make conflict resolution work. It
does not actually implement all the semantics that a revisioning
storage needs! """
self._lock_acquire()
try:
data = self._conflict_cache.get((oid, serial), marker)
if data is marker:
# XXX Need 2 serialnos to pass them to ConflictError--
# the old and the new
raise POSException.ConflictError(oid=oid)
else:
return data[0] # data here is actually (data, t)
finally:
self._lock_release()
</code>
2007/1/25, Martijn Pieters <mj at zopatista.com>:
>
> On 1/24/07, Maciej Wisniowski <maciej.wisniowski at coig.katowice.pl> wrote:
> > Another question, do you use ZEO? I know there were some issues
> > with _p_resolveConflict and ZEO (at last in Zope 2.8.x). Result
> > was that with ZEO setup _p_resolveConflict was not called at all.
> > There is solution for this but I don't know if this is your case
> > especially that you are dealing with TemporaryStorage which is
> > typically managed by ZEO Client...
>
> If ZEO cannot reach your product (import it), it cannot run any
> conflict resolution. Make sure that the ZEO server setup has access to
> those Products that do conflict resolution.
>
> --
> Martijn Pieters
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/zope/attachments/20070125/066fa7af/attachment-0001.htm
More information about the Zope
mailing list