[ZODB-Dev] Inconsistent use of ConflictError

Jim Fulton jim@zope.com
Thu, 16 Aug 2001 14:59:03 -0400


I agree with your analysis. Thanks. When you all figure out how this should
work, I'll check it in. :)

Some comments:

  - Serials are binary strings. Think of them as revision ids.

  - There should be a keyword argument/property to indicate read vs write
    conflicts.  Maybe we should make subclasses to indicate these and
    other kinds of conflicts.

  - We should define methods, not attributes for getting at bits of data.

Jim  

Greg Ward wrote:
> 
> This doesn't bother me much anymore now that we're not seeing
> ConflictError in practice (thanks to Connection.sync()), but it still
> bugs me that ZODB is inconsistent in how it uses ConflictError.
> 
> In particular, ConflictError appears to be raised in no fewer than 6
> different ways throughout the ZODB/ZEO code (ignoring trivial
> differences like "raise ConflictError" vs. "raise
> POSException.ConflictError"):
> 
>   raise ConflictError, `oid`
> 
>   raise ConflictError(`oid`, `object.__class__`)
> 
>   raise ConflictError, "transaction already invalidated"
> 
>   raise POSException.ConflictError
> 
>   raise POSException.ConflictError, (serial, oserial)
> 
>   raise POSException.ConflictError(
>                         'serial number mismatch (was: %s, has: %s)' %
>                         (utils.U64(oserial), utils.U64(serial)))
> 
> Do a recursive grep for "raise.*ConflictError" in StandaloneZODB to see
> for yourself.
> 
> This inconsistency makes it pretty much impossible to do anything with
> the exception value; from an API point of view, all of the above might
> as well be a bare "raise ConflictError".
> 
> Proposal:
>   * give ConflictError an actual interface, ie. some attributes,
>     a constructor with keyword arguments, and a __str__() to format
>     the error meaningfully
>   * fix all occurences of "raise ConflictError" to conform to
>     the new interface
> 
> Here's a strawman class definition:
> 
>   class ConflictError(TransactionError):
>       """
> 
>       Instance attributes:
>         oid : string
>           the OID (8-byte packed string) of the object in conflict
>         klass_name : string
>           the fully-qualified name of that object's class
>         message : string
>           a human-readable explanation of the error
>         serials : (???, ???)
>           pair of mystery objects -- I have no idea what these are,
>           I'm just including them because bsddb3Storage/*.py want
>           to provide this info
> 
>       """
> 
>       def __init__(self, message=None,
>                    oid=None, klass_name=None, serials=None):
>           # message would default to something like
>           # "database conflict error"
> 
>       def __str__ (self):
>           return self.message  # with some or all of oid, klass_name, and
>                                # serials pasted on in a meaningful way
> 
> Hmmm, the ConflictError docstring should mention that conflicts can
> occur on read as well.
> 
> Thoughts?
> 
>         Greg
> --
> Greg Ward - software developer                gward@mems-exchange.org
> MEMS Exchange                            http://www.mems-exchange.org
> 
> _______________________________________________
> For more information about ZODB, see the ZODB Wiki:
> http://www.zope.org/Wikis/ZODB/
> 
> ZODB-Dev mailing list  -  ZODB-Dev@zope.org
> http://lists.zope.org/mailman/listinfo/zodb-dev

--
Jim Fulton           mailto:jim@zope.com       Python Powered!        
Technical Director   (888) 344-4332            http://www.python.org  
Zope Corporation     http://www.zope.com       http://www.zope.org