From jeremy at zope.com Tue Mar 5 14:31:16 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO/zrpc - connection.py:1.1.2.6 Message-ID: <200203051931.g25JVGg08217@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO/zrpc In directory cvs.zope.org:/tmp/cvs-serv8202 Modified Files: Tag: Standby-branch connection.py Log Message: Add stub set_async() methods in classes that should ignore async mode. === ZEO/ZEO/zrpc/connection.py 1.1.2.5 => 1.1.2.6 === pass + def set_async(self, map): + pass + # XXX _do_async_loop is never called. Should it be defined as # above anyway? @@ -323,6 +326,9 @@ def close_trigger(self): # the manager should actually close the trigger del self.trigger + + def set_async(self, map): + pass def _prepare_async(self): # Don't do the register_loop_callback that the superclass does From jeremy at zope.com Thu Mar 7 21:10:03 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - Cache.py:1.3.2.2 Message-ID: <200203080210.g282A3C05470@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv5441 Modified Files: Tag: zeo-1_0-branch Cache.py Log Message: Don't use self._transaction === StandaloneZODB/ZEO/tests/Cache.py 1.3.2.1 => 1.3.2.2 === # Now start an undo transaction - self._transaction.note('undo1') - self._storage.tpc_begin(self._transaction) + t = Transaction() + t.note('undo1') + self._storage.tpc_begin(t) - oids = self._storage.transactionalUndo(tid, self._transaction) + oids = self._storage.transactionalUndo(tid, t) # Make sure this doesn't load invalid data into the cache self._storage.load(oid, '') - self._storage.tpc_vote(self._transaction) - self._storage.tpc_finish(self._transaction) + self._storage.tpc_vote(t) + self._storage.tpc_finish(t) assert len(oids) == 1 assert oids[0] == oid From jeremy at zope.com Thu Mar 7 21:12:40 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - testZEO.py:1.9.2.7 Message-ID: <200203080212.g282CeX07081@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv7058 Modified Files: Tag: zeo-1_0-branch testZEO.py Log Message: Add two new tests of the distributed commit lock. The tests cover the normal case (a waiting transaction begins) and the specific error case that the client disconnects before its transaction gets a chance to run. There is no test of non-disconnect errors. === StandaloneZODB/ZEO/tests/testZEO.py 1.9.2.6 => 1.9.2.7 === import ThreadedAsync, ZEO.trigger from ZODB.FileStorage import FileStorage +from ZODB.TimeStamp import TimeStamp +from ZODB.Transaction import Transaction import thread from ZEO.tests import forker, Cache @@ -72,15 +74,15 @@ if version is None: version = '' # Begin the transaction - self._storage.tpc_begin(self._transaction) + t = Transaction() + self._storage.tpc_begin(t) # Store an object - r1 = self._storage.store(oid, revid, data, version, - self._transaction) + r1 = self._storage.store(oid, revid, data, version, t) s1 = self._get_serial(r1) # Finish the transaction - r2 = self._storage.tpc_vote(self._transaction) + r2 = self._storage.tpc_vote(t) s2 = self._get_serial(r2) - self._storage.tpc_finish(self._transaction) + self._storage.tpc_finish(t) # s1, s2 can be None or dict assert not (s1 and s2) return s1 and s1[oid] or s2 and s2[oid] @@ -142,13 +144,13 @@ The ZEO server uses the storage object returned by the getStorage() method. """ + self.__super_setUp() self.running = 1 client, exit, pid = forker.start_zeo(self.getStorage()) self._pid = pid self._server = exit self._storage = PackWaitWrapper(client) client.registerDB(DummyDB(), None) - self.__super_setUp() def tearDown(self): """Try to cause the tests to halt""" @@ -159,9 +161,66 @@ self.delStorage() self.__super_tearDown() + def checkTwoArgBegin(self): + # XXX ZEO doesn't support 2-arg begin + pass + def checkLargeUpdate(self): obj = MinPO("X" * (10 * 128 * 1024)) self._dostore(data=obj) + + def checkCommitLockOnCommit(self): + self._checkCommitLock("tpc_finish") + + def checkCommitLockOnAbort(self): + self._checkCommitLock("tpc_abort") + + def _checkCommitLock(self, method_name): + # check the commit lock when a client attemps a transaction, + # but fails/exits before finishing the commit. + + # Start on transaction normally. + t = Transaction() + self._storage.tpc_begin(t) + + # Start a second transaction on a different connection without + # blocking the test thread. + self._storages = [] + for i in range(3): + storage2 = self._duplicate_client() + t2 = Transaction() + tid = self._get_timestamp() + storage2._call.sendMessage('tpc_begin_sync', + tid, t2.user, t2.description, + t2._extension) + if i == 0: + storage2.close() + else: + self._storages.append((storage2, t2)) + + oid = self._storage.new_oid() + self._storage.store(oid, None, '', '', t) + self._storage.tpc_vote(t) + self._storage.tpc_finish(t) + + for store, trans in self._storages: + store.tpc_abort(trans) + store.close() + + # Make sure the server is still responsive + self._dostore() + + def _duplicate_client(self): + "Open another ClientStorage to the same server." + addr = self._storage._connection + new = ZEO.ClientStorage.ClientStorage(addr) + new.registerDB(DummyDB(), None) + return new + + def _get_timestamp(self): + t = time.time() + t = apply(TimeStamp,(time.gmtime(t)[:5]+(t%60,))) + return 't' class ZEOFileStorageTests(GenericTests): __super_setUp = GenericTests.setUp From jeremy at zope.com Thu Mar 7 21:16:55 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.28.2.7 Message-ID: <200203080216.g282Gtc09243@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv9224 Modified Files: Tag: zeo-1_0-branch StorageServer.py Log Message: Refactor and fix distributed commit lock implementation. This is a candidate for ZEO 1.0b6. This fixes a bug reported by Chris McDonough on zodb-dev. The bug caused the storage server to stop committing transactions for a storage. The details of the bug are the in the checkCommitLock test cases. The following comment explains the new code. # distributed commit lock support methods # Only one client at a time can commit a transaction on a # storage. If one client is committing a transaction, and a # second client sends a tpc_begin(), then second client is queued. # When the first transaction finishes, either by abort or commit, # the request from the queued client must be handled. # It is important that this code be robust. If a queued # transaction is not restarted, the server will stop processing # new transactions. # This lock is implemented by storing the queued requests in a # list on the storage object. The list contains: # a callable object to resume request # arguments to that object # a callable object to handle errors during resume # XXX I am not sure that the commitlock_resume() method is # sufficiently paranoid. === StandaloneZODB/ZEO/StorageServer.py 1.28.2.6 => 1.28.2.7 === from ZEO import trigger from ZEO import asyncwrap +from ZEO.smac import Disconnected from types import StringType class StorageServerError(POSException.StorageError): pass @@ -133,6 +134,8 @@ self.__storages=storages for n, s in storages.items(): init_storage(s) + # Create a waiting list to support the distributed commit lock. + s._waiting = [] self.__connections={} self.__get_connections=self.__connections.get @@ -280,6 +283,7 @@ # This is the first communication from the client self.__storage, self.__storage_id = ( self.__server.register_connection(self, message)) + # Send info back asynchronously, so client need not ask self.message_output('S'+dump(self.get_info(), 1)) return @@ -501,39 +505,76 @@ return oids return () - def tpc_abort(self, id): - t=self._transaction - if t is None or id != t.id: return - r=self.__storage.tpc_abort(t) + # distributed commit lock support methods - storage=self.__storage - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] + # Only one client at a time can commit a transaction on a + # storage. If one client is committing a transaction, and a + # second client sends a tpc_begin(), then second client is queued. + # When the first transaction finishes, either by abort or commit, + # the request from the queued client must be handled. + + # It is important that this code be robust. If a queued + # transaction is not restarted, the server will stop processing + # new transactions. + + # This lock is implemented by storing the queued requests in a + # list on the storage object. The list contains: + # a callable object to resume request + # arguments to that object + # a callable object to handle errors during resume + + # XXX I am not sure that the commitlock_resume() method is + # sufficiently paranoid. + + def commitlock_suspend(self, resume, args, onerror): + self.__storage._waiting.append((resume, args, onerror)) + + def commitlock_resume(self): + waiting = self.__storage._waiting while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + resume, args, onerror = waiting.pop(0) + try: + if apply(resume, args): + break + except Disconnected: + # A disconnected error isn't an unexpected error. + # There should be no need to log it, because the + # disconnect will have generated its own log event. + onerror() + except: + LOG('ZEO Server', ERROR, + "Unexpected error handling queued tpc_begin()", + error=sys.exc_info()) + onerror() - self._transaction=None - self.__invalidated=[] + def tpc_abort(self, id): + t = self._transaction + if t is None or id != t.id: + return + r = self.__storage.tpc_abort(t) + + self._transaction = None + self.__invalidated = [] + self.commitlock_resume() def unlock(self): - if self.__closed: return + if self.__closed: + return self.message_output('UN.') def tpc_begin(self, id, user, description, ext): - t=self._transaction + t = self._transaction if t is not None: - if id == t.id: return + if id == t.id: + return else: raise StorageServerError( "Multiple simultaneous tpc_begin requests from the same " "client." ) - storage=self.__storage + storage = self.__storage if storage._transaction is not None: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.unlock, ())) + self.commitlock_suspend(self.unlock, (), self.close) return 1 # Return a flag indicating a lock condition. self._transaction=t=Transaction() @@ -552,9 +593,9 @@ if storage._transaction is None: self.try_again_sync(id, user, description, ext) else: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.try_again_sync, (id, user, description, ext))) + self.commitlock_suspend(self.try_again_sync, + (id, user, description, ext), + self.close) return _noreturn @@ -572,24 +613,21 @@ return 1 def tpc_finish(self, id, user, description, ext): - t=self._transaction - if id != t.id: return + t = self._transaction + if id != t.id: + return - storage=self.__storage - r=storage.tpc_finish(t) - - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + storage = self.__storage + r = storage.tpc_finish(t) - self._transaction=None + self._transaction = None if self.__invalidated: self.__server.invalidate(self, self.__storage_id, self.__invalidated, self.get_size_info()) - self.__invalidated=[] + self.__invalidated = [] + + self.commitlock_resume() def init_storage(storage): if not hasattr(storage,'tpc_vote'): storage.tpc_vote=lambda *args: None From jeremy at zope.com Fri Mar 8 15:35:04 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - ClientCache.py:1.16.2.4 ClientStorage.py:1.33.2.7 Invalidator.py:1.5.2.2 StorageServer.py:1.28.2.8 __init__.py:1.7.2.1 asyncwrap.py:1.1.2.2 fap.py:1.5.2.1 smac.py:1.10.2.2 start.py:1.24.2.2 trigger.py:1.1.8.4 zrpc.py:1.18.2.7 Message-ID: <200203082035.g28KZ4s21929@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv21790 Modified Files: Tag: zeo-1_0-branch ClientCache.py ClientStorage.py Invalidator.py StorageServer.py __init__.py asyncwrap.py fap.py smac.py start.py trigger.py zrpc.py Log Message: Upgrade license to ZPL 2.0 === StandaloneZODB/ZEO/ClientCache.py 1.16.2.3 => 1.16.2.4 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## """Implement a client cache === StandaloneZODB/ZEO/ClientStorage.py 1.33.2.6 => 1.33.2.7 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## """Network ZODB storage client === StandaloneZODB/ZEO/Invalidator.py 1.5.2.1 => 1.5.2.2 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## """Facility for (roughly) atomically invalidating cache entries. === StandaloneZODB/ZEO/StorageServer.py 1.28.2.7 => 1.28.2.8 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## === StandaloneZODB/ZEO/__init__.py 1.7 => 1.7.2.1 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## === StandaloneZODB/ZEO/asyncwrap.py 1.1.2.1 => 1.1.2.2 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """A wrapper for asyncore that provides robust exception handling. The poll() and loop() calls exported by asyncore can raise exceptions. === StandaloneZODB/ZEO/fap.py 1.5 => 1.5.2.1 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## === StandaloneZODB/ZEO/smac.py 1.10.2.1 => 1.10.2.2 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## """Sized message async connections === StandaloneZODB/ZEO/start.py 1.24.2.1 => 1.24.2.2 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## === StandaloneZODB/ZEO/trigger.py 1.1.8.3 => 1.1.8.4 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## === StandaloneZODB/ZEO/zrpc.py 1.18.2.6 => 1.18.2.7 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## """Simple rpc mechanisms From jeremy at zope.com Fri Mar 8 15:35:11 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - Cache.py:1.3.2.3 __init__.py:1.2.2.1 forker.py:1.5.2.8 multi.py:1.3.2.2 speed.py:1.4.2.2 stress.py:1.1.2.2 testZEO.py:1.9.2.8 winserver.py:1.2.2.2 Message-ID: <200203082035.g28KZBN22053@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv21965 Modified Files: Tag: zeo-1_0-branch Cache.py __init__.py forker.py multi.py speed.py stress.py testZEO.py winserver.py Log Message: Upgrade license to ZPL 2.0 === StandaloneZODB/ZEO/tests/Cache.py 1.3.2.2 => 1.3.2.3 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """Tests of the ZEO cache""" from ZODB.Transaction import Transaction === StandaloneZODB/ZEO/tests/__init__.py 1.2 => 1.2.2.1 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## === StandaloneZODB/ZEO/tests/forker.py 1.5.2.7 => 1.5.2.8 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """Library for forking storage server and connecting client storage""" import asyncore === StandaloneZODB/ZEO/tests/multi.py 1.3.2.1 => 1.3.2.2 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """A multi-client test of the ZEO storage server""" import ZODB, ZODB.DB, ZODB.FileStorage, ZODB.POSException === StandaloneZODB/ZEO/tests/speed.py 1.4.2.1 => 1.4.2.2 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## usage="""Test speed of a ZODB storage === StandaloneZODB/ZEO/tests/stress.py 1.1.2.1 => 1.1.2.2 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """A ZEO client-server stress test to look for leaks. The stress test should run in an infinite loop and should involve === StandaloneZODB/ZEO/tests/testZEO.py 1.9.2.7 => 1.9.2.8 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """Test suite for ZEO based on ZODB.tests""" import asyncore === StandaloneZODB/ZEO/tests/winserver.py 1.2.2.1 => 1.2.2.2 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## """Helper file used to launch ZEO server for Windows tests""" import asyncore From jeremy at zope.com Fri Mar 8 15:35:38 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: ZEO - LICENSE.txt:1.1.2.1 Message-ID: <200203082035.g28KZcd22225@cvs.baymountain.com> Update of /cvs-repository/ZEO In directory cvs.zope.org:/tmp/cvs-serv22211 Added Files: Tag: zeo-1_0-branch LICENSE.txt Log Message: Upgrade license to ZPL 2.0 === Added File ZEO/LICENSE.txt === Zope Public License (ZPL) Version 2.0 ----------------------------------------------- This software is Copyright (c) Zope Corporation (tm) and Contributors. All rights reserved. This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name Zope Corporation (tm) must not be used to endorse or promote products derived from this software without prior written permission from Zope Corporation. 4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of Zope Corporation. Use of them is covered in a separate agreement (see http://www.zope.com/Marks). 5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. Disclaimer THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of contributions made by Zope Corporation and many individuals on behalf of Zope Corporation. Specific attributions are listed in the accompanying credits file. From jeremy at zope.com Fri Mar 8 15:35:59 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: ZEO - CHANGES.txt:1.25.2.6 Message-ID: <200203082035.g28KZxE22336@cvs.baymountain.com> Update of /cvs-repository/ZEO In directory cvs.zope.org:/tmp/cvs-serv22327 Modified Files: Tag: zeo-1_0-branch CHANGES.txt Log Message: Add explanation of bug found in 1.0b5. === ZEO/CHANGES.txt 1.25.2.5 => 1.25.2.6 === + ZEO 1.0 beta 6 + + Bugs fixed + + - Fixed a bug that could cause the server to stop committing + transactions for a storage. The bug occurred under the + following circumstances: + + - A synchronous client made a tpc_begin() request. + - The request arrived while another transaction was in + progress. + - The other transaction finished. + - The client closed the connection or an unexpected error + occurred while the server was handling the client's + tpc_begin(). + + The fix is to make the code to resume a waiting transaction + robust in the face of disconnects and errors. + + Upgrade to license to ZPL 2.0 + ZEO 1.0 beta 5 Bugs fixed From jeremy at zope.com Fri Mar 15 00:11:53 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - ClientCache.py:1.22 ClientStorage.py:1.39 StorageServer.py:1.35 asyncwrap.py:1.4 smac.py:1.15 start.py:1.30 zrpc.py:1.22 Message-ID: <200203150511.g2F5BrA27620@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv27595 Modified Files: ClientCache.py ClientStorage.py StorageServer.py asyncwrap.py smac.py start.py zrpc.py Log Message: Merge changes from the zeo-1_0-branch onto the debug branch === StandaloneZODB/ZEO/ClientCache.py 1.21 => 1.22 === === StandaloneZODB/ZEO/ClientStorage.py 1.38 => 1.39 === """Network ZODB storage client """ - __version__='$Revision$'[11:-2] import struct, time, os, socket, string, Sync, zrpc, ClientCache === StandaloneZODB/ZEO/StorageServer.py 1.34 => 1.35 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## @@ -99,6 +28,7 @@ from cStringIO import StringIO from ZEO import trigger from ZEO import asyncwrap +from ZEO.smac import Disconnected from types import StringType class StorageServerError(POSException.StorageError): pass @@ -133,6 +63,8 @@ self.__storages=storages for n, s in storages.items(): init_storage(s) + # Create a waiting list to support the distributed commit lock. + s._waiting = [] self.__connections={} self.__get_connections=self.__connections.get @@ -280,6 +212,7 @@ # This is the first communication from the client self.__storage, self.__storage_id = ( self.__server.register_connection(self, message)) + # Send info back asynchronously, so client need not ask self.message_output('S'+dump(self.get_info(), 1)) return @@ -501,39 +434,76 @@ return oids return () - def tpc_abort(self, id): - t=self._transaction - if t is None or id != t.id: return - r=self.__storage.tpc_abort(t) + # distributed commit lock support methods - storage=self.__storage - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] + # Only one client at a time can commit a transaction on a + # storage. If one client is committing a transaction, and a + # second client sends a tpc_begin(), then second client is queued. + # When the first transaction finishes, either by abort or commit, + # the request from the queued client must be handled. + + # It is important that this code be robust. If a queued + # transaction is not restarted, the server will stop processing + # new transactions. + + # This lock is implemented by storing the queued requests in a + # list on the storage object. The list contains: + # a callable object to resume request + # arguments to that object + # a callable object to handle errors during resume + + # XXX I am not sure that the commitlock_resume() method is + # sufficiently paranoid. + + def commitlock_suspend(self, resume, args, onerror): + self.__storage._waiting.append((resume, args, onerror)) + + def commitlock_resume(self): + waiting = self.__storage._waiting while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + resume, args, onerror = waiting.pop(0) + try: + if apply(resume, args): + break + except Disconnected: + # A disconnected error isn't an unexpected error. + # There should be no need to log it, because the + # disconnect will have generated its own log event. + onerror() + except: + LOG('ZEO Server', ERROR, + "Unexpected error handling queued tpc_begin()", + error=sys.exc_info()) + onerror() - self._transaction=None - self.__invalidated=[] + def tpc_abort(self, id): + t = self._transaction + if t is None or id != t.id: + return + r = self.__storage.tpc_abort(t) + + self._transaction = None + self.__invalidated = [] + self.commitlock_resume() def unlock(self): - if self.__closed: return + if self.__closed: + return self.message_output('UN.') def tpc_begin(self, id, user, description, ext): - t=self._transaction + t = self._transaction if t is not None: - if id == t.id: return + if id == t.id: + return else: raise StorageServerError( "Multiple simultaneous tpc_begin requests from the same " "client." ) - storage=self.__storage + storage = self.__storage if storage._transaction is not None: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.unlock, ())) + self.commitlock_suspend(self.unlock, (), self.close) return 1 # Return a flag indicating a lock condition. self._transaction=t=Transaction() @@ -552,9 +522,9 @@ if storage._transaction is None: self.try_again_sync(id, user, description, ext) else: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.try_again_sync, (id, user, description, ext))) + self.commitlock_suspend(self.try_again_sync, + (id, user, description, ext), + self.close) return _noreturn @@ -572,24 +542,21 @@ return 1 def tpc_finish(self, id, user, description, ext): - t=self._transaction - if id != t.id: return + t = self._transaction + if id != t.id: + return - storage=self.__storage - r=storage.tpc_finish(t) - - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + storage = self.__storage + r = storage.tpc_finish(t) - self._transaction=None + self._transaction = None if self.__invalidated: self.__server.invalidate(self, self.__storage_id, self.__invalidated, self.get_size_info()) - self.__invalidated=[] + self.__invalidated = [] + + self.commitlock_resume() def init_storage(storage): if not hasattr(storage,'tpc_vote'): storage.tpc_vote=lambda *args: None === StandaloneZODB/ZEO/asyncwrap.py 1.3 => 1.4 === # ############################################################################## - """A wrapper for asyncore that provides robust exception handling. The poll() and loop() calls exported by asyncore can raise exceptions. @@ -31,6 +30,10 @@ it would be useful to extend this module with wrappers for those errors. """ + +# XXX The current implementation requires Python 2.0. Not sure if +# that's acceptable, depends on how many users want to combine ZEO 1.0 +# and Zope 2.3. import asyncore import errno === StandaloneZODB/ZEO/smac.py 1.14 => 1.15 === === StandaloneZODB/ZEO/start.py 1.29 => 1.30 === else: # Hm, lets at least try to take care of the stupid logger: - if hasattr(zLOG, '_set_stupid_dest'): - zLOG._set_stupid_dest(None) - else: - zLOG._stupid_dest = None + zLOG._stupid_dest=None def rotate_logs_handler(signum, frame): rotate_logs() === StandaloneZODB/ZEO/zrpc.py 1.21 => 1.22 === From jeremy at zope.com Fri Mar 15 00:11:55 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - Cache.py:1.7 __init__.py:1.3 forker.py:1.15 multi.py:1.7 stress.py:1.5 testZEO.py:1.22 winserver.py:1.4 Message-ID: <200203150511.g2F5BtY27673@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv27625 Modified Files: Cache.py __init__.py forker.py multi.py stress.py testZEO.py winserver.py Log Message: Merge changes from the zeo-1_0-branch onto the debug branch === StandaloneZODB/ZEO/tests/Cache.py 1.6 => 1.7 === # ############################################################################## - """Tests of the ZEO cache""" from ZODB.Transaction import Transaction === StandaloneZODB/ZEO/tests/__init__.py 1.2 => 1.3 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## === StandaloneZODB/ZEO/tests/forker.py 1.14 => 1.15 === # ############################################################################## - """Library for forking storage server and connecting client storage""" import asyncore @@ -62,7 +61,7 @@ args = (sys.executable, script, str(port), storage_name) + args d = os.environ.copy() d['PYTHONPATH'] = os.pathsep.join(sys.path) - pid = os.spawnve(os.P_NOWAIT, sys.executable, args, d) + pid = os.spawnve(os.P_NOWAIT, sys.executable, args, os.environ) return ('localhost', port), ('localhost', port + 1), pid else: @@ -98,16 +97,14 @@ rd, wr = os.pipe() pid = os.fork() if pid == 0: - try: - if PROFILE: - p = profile.Profile() - p.runctx("run_server(storage, addr, rd, wr)", globals(), - locals()) - p.dump_stats("stats.s.%d" % os.getpid()) - else: - run_server(storage, addr, rd, wr) - finally: - os._exit(0) + if PROFILE: + p = profile.Profile() + p.runctx("run_server(storage, addr, rd, wr)", globals(), + locals()) + p.dump_stats("stats.s.%d" % os.getpid()) + else: + run_server(storage, addr, rd, wr) + os._exit(0) else: os.close(rd) return pid, ZEOClientExit(wr) === StandaloneZODB/ZEO/tests/multi.py 1.6 => 1.7 === # ############################################################################## - """A multi-client test of the ZEO storage server""" import ZODB, ZODB.DB, ZODB.FileStorage, ZODB.POSException @@ -70,18 +69,16 @@ def start_client(addr, client_func=None): pid = os.fork() if pid == 0: - try: - import ZEO.ClientStorage - if VERBOSE: - print "Client process started:", os.getpid() - cli = ZEO.ClientStorage.ClientStorage(addr, client=CLIENT_CACHE) - if client_func is None: - run(cli) - else: - client_func(cli) - cli.close() - finally: - os._exit(0) + import ZEO.ClientStorage + if VERBOSE: + print "Client process started:", os.getpid() + cli = ZEO.ClientStorage.ClientStorage(addr, client=CLIENT_CACHE) + if client_func is None: + run(cli) + else: + client_func(cli) + cli.close() + os._exit(0) else: return pid === StandaloneZODB/ZEO/tests/stress.py 1.4 => 1.5 === # ############################################################################## - """A ZEO client-server stress test to look for leaks. The stress test should run in an infinite loop and should involve @@ -105,34 +104,32 @@ if pid != 0: return pid - try: - storage = ClientStorage(zaddr, debug=1, min_disconnect_poll=0.5) - db = ZODB.DB(storage, pool_size=NUM_CONNECTIONS) - setup(db.open()) - conns = [] - conn_count = 0 - - for i in range(NUM_CONNECTIONS): + storage = ClientStorage(zaddr, debug=1, min_disconnect_poll=0.5) + db = ZODB.DB(storage, pool_size=NUM_CONNECTIONS) + setup(db.open()) + conns = [] + conn_count = 0 + + for i in range(NUM_CONNECTIONS): + c = db.open() + c.__count = 0 + conns.append(c) + conn_count += 1 + + while conn_count < 25: + c = random.choice(conns) + if c.__count > NUM_TRANSACTIONS_PER_CONN: + conns.remove(c) + c.close() + conn_count += 1 c = db.open() c.__count = 0 conns.append(c) - conn_count += 1 - - while conn_count < 25: - c = random.choice(conns) - if c.__count > NUM_TRANSACTIONS_PER_CONN: - conns.remove(c) - c.close() - conn_count += 1 - c = db.open() - c.__count = 0 - conns.append(c) - else: - c.__count += 1 - work(c) + else: + c.__count += 1 + work(c) - finally: - os._exit(0) + os._exit(0) if __name__ == "__main__": main() === StandaloneZODB/ZEO/tests/testZEO.py 1.21 => 1.22 === # ############################################################################## - """Test suite for ZEO based on ZODB.tests""" import asyncore @@ -27,6 +26,8 @@ import ZEO.ClientStorage, ZEO.StorageServer import ThreadedAsync, ZEO.trigger from ZODB.FileStorage import FileStorage +from ZODB.TimeStamp import TimeStamp +from ZODB.Transaction import Transaction import thread from ZEO.tests import forker, Cache @@ -35,7 +36,7 @@ # Sorry Jim... from ZODB.tests import StorageTestBase, BasicStorage, VersionStorage, \ TransactionalUndoStorage, TransactionalUndoVersionStorage, \ - PackableStorage, Synchronization, ConflictResolution, RevisionStorage + PackableStorage, Synchronization, ConflictResolution from ZODB.tests.MinPO import MinPO from ZODB.tests.StorageTestBase import zodb_unpickle @@ -56,9 +57,63 @@ self.storage.pack(t, f, wait=1) class ZEOTestBase(StorageTestBase.StorageTestBase): - """Version of the storage test class that supports ZEO.""" - pass + """Version of the storage test class that supports ZEO. + + For ZEO, we don't always get the serialno/exception for a + particular store as the return value from the store. But we + will get no later than the return value from vote. + """ + def _dostore(self, oid=None, revid=None, data=None, version=None, + already_pickled=0): + """Do a complete storage transaction. + + The defaults are: + - oid=None, ask the storage for a new oid + - revid=None, use a revid of ZERO + - data=None, pickle up some arbitrary data (the integer 7) + - version=None, use the empty string version + + Returns the object's new revision id. + """ + if oid is None: + oid = self._storage.new_oid() + if revid is None: + revid = ZERO + if data is None: + data = MinPO(7) + if not already_pickled: + data = StorageTestBase.zodb_pickle(data) + if version is None: + version = '' + # Begin the transaction + t = Transaction() + self._storage.tpc_begin(t) + # Store an object + r1 = self._storage.store(oid, revid, data, version, t) + s1 = self._get_serial(r1) + # Finish the transaction + r2 = self._storage.tpc_vote(t) + s2 = self._get_serial(r2) + self._storage.tpc_finish(t) + # s1, s2 can be None or dict + assert not (s1 and s2) + return s1 and s1[oid] or s2 and s2[oid] + + def _get_serial(self, r): + """Return oid -> serialno dict from sequence of ZEO replies.""" + d = {} + if r is None: + return None + if type(r) == types.StringType: + raise RuntimeError, "unexpected ZEO response: no oid" + else: + for oid, serial in r: + if isinstance(serial, Exception): + raise serial + d[oid] = serial + return d + # Some of the ZEO tests depend on the version of FileStorage available # for the tests. If we run these tests using Zope 2.3, FileStorage # doesn't support TransactionalUndo. @@ -75,14 +130,13 @@ else: class VersionDependentTests: pass - + class GenericTests(ZEOTestBase, VersionDependentTests, Cache.StorageWithCache, Cache.TransUndoStorageWithCache, BasicStorage.BasicStorage, VersionStorage.VersionStorage, - RevisionStorage.RevisionStorage, PackableStorage.PackableStorage, Synchronization.SynchronizedStorage, ): @@ -94,12 +148,16 @@ returns a specific storage, e.g. FileStorage. """ + __super_setUp = StorageTestBase.StorageTestBase.setUp + __super_tearDown = StorageTestBase.StorageTestBase.tearDown + def setUp(self): """Start a ZEO server using a Unix domain socket The ZEO server uses the storage object returned by the getStorage() method. """ + self.__super_setUp() self.running = 1 client, exit, pid = forker.start_zeo(self.getStorage()) self._pid = pid @@ -114,13 +172,68 @@ self._server.close() os.waitpid(self._pid, 0) self.delStorage() + self.__super_tearDown() + + def checkTwoArgBegin(self): + # XXX ZEO doesn't support 2-arg begin + pass def checkLargeUpdate(self): obj = MinPO("X" * (10 * 128 * 1024)) self._dostore(data=obj) - def checkTwoArgBegin(self): - pass # ZEO 1 doesn't support two-arg begin + def checkCommitLockOnCommit(self): + self._checkCommitLock("tpc_finish") + + def checkCommitLockOnAbort(self): + self._checkCommitLock("tpc_abort") + + def _checkCommitLock(self, method_name): + # check the commit lock when a client attemps a transaction, + # but fails/exits before finishing the commit. + + # Start on transaction normally. + t = Transaction() + self._storage.tpc_begin(t) + + # Start a second transaction on a different connection without + # blocking the test thread. + self._storages = [] + for i in range(3): + storage2 = self._duplicate_client() + t2 = Transaction() + tid = self._get_timestamp() + storage2._call.sendMessage('tpc_begin_sync', + tid, t2.user, t2.description, + t2._extension) + if i == 0: + storage2.close() + else: + self._storages.append((storage2, t2)) + + oid = self._storage.new_oid() + self._storage.store(oid, None, '', '', t) + self._storage.tpc_vote(t) + self._storage.tpc_finish(t) + + for store, trans in self._storages: + store.tpc_abort(trans) + store.close() + + # Make sure the server is still responsive + self._dostore() + + def _duplicate_client(self): + "Open another ClientStorage to the same server." + addr = self._storage._connection + new = ZEO.ClientStorage.ClientStorage(addr) + new.registerDB(DummyDB(), None) + return new + + def _get_timestamp(self): + t = time.time() + t = apply(TimeStamp,(time.gmtime(t)[:5]+(t%60,))) + return 't' class ZEOFileStorageTests(GenericTests): __super_setUp = GenericTests.setUp @@ -148,8 +261,11 @@ can't be created in the parent process and passed to the child. All the work has to be done in the server's process. """ + __super_setUp = StorageTestBase.StorageTestBase.setUp + __super_tearDown = StorageTestBase.StorageTestBase.tearDown def setUp(self): + self.__super_setUp() args = self.getStorageInfo() name = args[0] args = args[1:] @@ -169,6 +285,7 @@ ## os.waitpid(self.test_pid, 0) time.sleep(0.5) self.delStorage() + self.__super_tearDown() class WindowsZEOFileStorageTests(WindowsGenericTests): @@ -192,6 +309,8 @@ start and stop a ZEO storage server. """ + __super_tearDown = StorageTestBase.StorageTestBase.tearDown + ports = [] for i in range(200): ports.append(random.randrange(25000, 30000)) @@ -207,7 +326,6 @@ def tearDown(self): """Try to cause the tests to halt""" - self._storage.close() self.shutdownServer() # file storage appears to create four files for ext in '', '.index', '.lock', '.tmp': @@ -218,6 +336,7 @@ path = "c1-test-%d.zec" % i if os.path.exists(path): os.unlink(path) + self.__super_tearDown() def checkBasicPersistence(self): """Verify cached data persists across client storage instances. === StandaloneZODB/ZEO/tests/winserver.py 1.3 => 1.4 === # ############################################################################## - """Helper file used to launch ZEO server for Windows tests""" import asyncore From jeremy at zope.com Fri Mar 15 00:17:52 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - ClientCache.py:1.21.2.1 ClientStorage.py:1.38.2.1 StorageServer.py:1.34.2.1 asyncwrap.py:1.3.2.1 smac.py:1.14.2.1 start.py:1.29.2.1 zrpc.py:1.21.2.1 Message-ID: <200203150517.g2F5HqL29042@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv29019 Modified Files: Tag: zeo-1_0-debug-branch ClientCache.py ClientStorage.py StorageServer.py asyncwrap.py smac.py start.py zrpc.py Log Message: Merge changes from the zeo-1_0-branch onto the debug branch (Take two. The previous checkin merged from the branch to the trunk, demonstrating that I'm good with branches regardless of whether they are long-lived.) === StandaloneZODB/ZEO/ClientCache.py 1.21 => 1.21.2.1 === === StandaloneZODB/ZEO/ClientStorage.py 1.38 => 1.38.2.1 === """Network ZODB storage client """ - __version__='$Revision$'[11:-2] import struct, time, os, socket, string, Sync, zrpc, ClientCache === StandaloneZODB/ZEO/StorageServer.py 1.34 => 1.34.2.1 === -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE # ############################################################################## @@ -99,6 +28,7 @@ from cStringIO import StringIO from ZEO import trigger from ZEO import asyncwrap +from ZEO.smac import Disconnected from types import StringType class StorageServerError(POSException.StorageError): pass @@ -133,6 +63,8 @@ self.__storages=storages for n, s in storages.items(): init_storage(s) + # Create a waiting list to support the distributed commit lock. + s._waiting = [] self.__connections={} self.__get_connections=self.__connections.get @@ -280,6 +212,7 @@ # This is the first communication from the client self.__storage, self.__storage_id = ( self.__server.register_connection(self, message)) + # Send info back asynchronously, so client need not ask self.message_output('S'+dump(self.get_info(), 1)) return @@ -501,39 +434,76 @@ return oids return () - def tpc_abort(self, id): - t=self._transaction - if t is None or id != t.id: return - r=self.__storage.tpc_abort(t) + # distributed commit lock support methods - storage=self.__storage - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] + # Only one client at a time can commit a transaction on a + # storage. If one client is committing a transaction, and a + # second client sends a tpc_begin(), then second client is queued. + # When the first transaction finishes, either by abort or commit, + # the request from the queued client must be handled. + + # It is important that this code be robust. If a queued + # transaction is not restarted, the server will stop processing + # new transactions. + + # This lock is implemented by storing the queued requests in a + # list on the storage object. The list contains: + # a callable object to resume request + # arguments to that object + # a callable object to handle errors during resume + + # XXX I am not sure that the commitlock_resume() method is + # sufficiently paranoid. + + def commitlock_suspend(self, resume, args, onerror): + self.__storage._waiting.append((resume, args, onerror)) + + def commitlock_resume(self): + waiting = self.__storage._waiting while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + resume, args, onerror = waiting.pop(0) + try: + if apply(resume, args): + break + except Disconnected: + # A disconnected error isn't an unexpected error. + # There should be no need to log it, because the + # disconnect will have generated its own log event. + onerror() + except: + LOG('ZEO Server', ERROR, + "Unexpected error handling queued tpc_begin()", + error=sys.exc_info()) + onerror() - self._transaction=None - self.__invalidated=[] + def tpc_abort(self, id): + t = self._transaction + if t is None or id != t.id: + return + r = self.__storage.tpc_abort(t) + + self._transaction = None + self.__invalidated = [] + self.commitlock_resume() def unlock(self): - if self.__closed: return + if self.__closed: + return self.message_output('UN.') def tpc_begin(self, id, user, description, ext): - t=self._transaction + t = self._transaction if t is not None: - if id == t.id: return + if id == t.id: + return else: raise StorageServerError( "Multiple simultaneous tpc_begin requests from the same " "client." ) - storage=self.__storage + storage = self.__storage if storage._transaction is not None: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.unlock, ())) + self.commitlock_suspend(self.unlock, (), self.close) return 1 # Return a flag indicating a lock condition. self._transaction=t=Transaction() @@ -552,9 +522,9 @@ if storage._transaction is None: self.try_again_sync(id, user, description, ext) else: - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - waiting.append((self.try_again_sync, (id, user, description, ext))) + self.commitlock_suspend(self.try_again_sync, + (id, user, description, ext), + self.close) return _noreturn @@ -572,24 +542,21 @@ return 1 def tpc_finish(self, id, user, description, ext): - t=self._transaction - if id != t.id: return + t = self._transaction + if id != t.id: + return - storage=self.__storage - r=storage.tpc_finish(t) - - try: waiting=storage.__waiting - except: waiting=storage.__waiting=[] - while waiting: - f, args = waiting.pop(0) - if apply(f,args): break + storage = self.__storage + r = storage.tpc_finish(t) - self._transaction=None + self._transaction = None if self.__invalidated: self.__server.invalidate(self, self.__storage_id, self.__invalidated, self.get_size_info()) - self.__invalidated=[] + self.__invalidated = [] + + self.commitlock_resume() def init_storage(storage): if not hasattr(storage,'tpc_vote'): storage.tpc_vote=lambda *args: None === StandaloneZODB/ZEO/asyncwrap.py 1.3 => 1.3.2.1 === # ############################################################################## - """A wrapper for asyncore that provides robust exception handling. The poll() and loop() calls exported by asyncore can raise exceptions. @@ -31,6 +30,10 @@ it would be useful to extend this module with wrappers for those errors. """ + +# XXX The current implementation requires Python 2.0. Not sure if +# that's acceptable, depends on how many users want to combine ZEO 1.0 +# and Zope 2.3. import asyncore import errno === StandaloneZODB/ZEO/smac.py 1.14 => 1.14.2.1 === === StandaloneZODB/ZEO/start.py 1.29 => 1.29.2.1 === else: # Hm, lets at least try to take care of the stupid logger: - if hasattr(zLOG, '_set_stupid_dest'): - zLOG._set_stupid_dest(None) - else: - zLOG._stupid_dest = None + zLOG._stupid_dest=None def rotate_logs_handler(signum, frame): rotate_logs() === StandaloneZODB/ZEO/zrpc.py 1.21 => 1.21.2.1 === From jeremy at zope.com Fri Mar 15 00:17:54 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - Cache.py:1.6.2.1 __init__.py:1.2.10.1 forker.py:1.14.2.1 multi.py:1.6.2.1 stress.py:1.4.2.1 testZEO.py:1.21.2.1 winserver.py:1.3.2.1 Message-ID: <200203150517.g2F5Hsl29070@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv29047 Modified Files: Tag: zeo-1_0-debug-branch Cache.py __init__.py forker.py multi.py stress.py testZEO.py winserver.py Log Message: Merge changes from the zeo-1_0-branch onto the debug branch (Take two. The previous checkin merged from the branch to the trunk, demonstrating that I'm good with branches regardless of whether they are long-lived.) === StandaloneZODB/ZEO/tests/Cache.py 1.6 => 1.6.2.1 === # ############################################################################## - """Tests of the ZEO cache""" from ZODB.Transaction import Transaction === StandaloneZODB/ZEO/tests/__init__.py 1.2 => 1.2.10.1 === +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## === StandaloneZODB/ZEO/tests/forker.py 1.14 => 1.14.2.1 === # ############################################################################## - """Library for forking storage server and connecting client storage""" import asyncore @@ -62,7 +61,7 @@ args = (sys.executable, script, str(port), storage_name) + args d = os.environ.copy() d['PYTHONPATH'] = os.pathsep.join(sys.path) - pid = os.spawnve(os.P_NOWAIT, sys.executable, args, d) + pid = os.spawnve(os.P_NOWAIT, sys.executable, args, os.environ) return ('localhost', port), ('localhost', port + 1), pid else: @@ -98,16 +97,14 @@ rd, wr = os.pipe() pid = os.fork() if pid == 0: - try: - if PROFILE: - p = profile.Profile() - p.runctx("run_server(storage, addr, rd, wr)", globals(), - locals()) - p.dump_stats("stats.s.%d" % os.getpid()) - else: - run_server(storage, addr, rd, wr) - finally: - os._exit(0) + if PROFILE: + p = profile.Profile() + p.runctx("run_server(storage, addr, rd, wr)", globals(), + locals()) + p.dump_stats("stats.s.%d" % os.getpid()) + else: + run_server(storage, addr, rd, wr) + os._exit(0) else: os.close(rd) return pid, ZEOClientExit(wr) === StandaloneZODB/ZEO/tests/multi.py 1.6 => 1.6.2.1 === # ############################################################################## - """A multi-client test of the ZEO storage server""" import ZODB, ZODB.DB, ZODB.FileStorage, ZODB.POSException @@ -70,18 +69,16 @@ def start_client(addr, client_func=None): pid = os.fork() if pid == 0: - try: - import ZEO.ClientStorage - if VERBOSE: - print "Client process started:", os.getpid() - cli = ZEO.ClientStorage.ClientStorage(addr, client=CLIENT_CACHE) - if client_func is None: - run(cli) - else: - client_func(cli) - cli.close() - finally: - os._exit(0) + import ZEO.ClientStorage + if VERBOSE: + print "Client process started:", os.getpid() + cli = ZEO.ClientStorage.ClientStorage(addr, client=CLIENT_CACHE) + if client_func is None: + run(cli) + else: + client_func(cli) + cli.close() + os._exit(0) else: return pid === StandaloneZODB/ZEO/tests/stress.py 1.4 => 1.4.2.1 === # ############################################################################## - """A ZEO client-server stress test to look for leaks. The stress test should run in an infinite loop and should involve @@ -105,34 +104,32 @@ if pid != 0: return pid - try: - storage = ClientStorage(zaddr, debug=1, min_disconnect_poll=0.5) - db = ZODB.DB(storage, pool_size=NUM_CONNECTIONS) - setup(db.open()) - conns = [] - conn_count = 0 - - for i in range(NUM_CONNECTIONS): + storage = ClientStorage(zaddr, debug=1, min_disconnect_poll=0.5) + db = ZODB.DB(storage, pool_size=NUM_CONNECTIONS) + setup(db.open()) + conns = [] + conn_count = 0 + + for i in range(NUM_CONNECTIONS): + c = db.open() + c.__count = 0 + conns.append(c) + conn_count += 1 + + while conn_count < 25: + c = random.choice(conns) + if c.__count > NUM_TRANSACTIONS_PER_CONN: + conns.remove(c) + c.close() + conn_count += 1 c = db.open() c.__count = 0 conns.append(c) - conn_count += 1 - - while conn_count < 25: - c = random.choice(conns) - if c.__count > NUM_TRANSACTIONS_PER_CONN: - conns.remove(c) - c.close() - conn_count += 1 - c = db.open() - c.__count = 0 - conns.append(c) - else: - c.__count += 1 - work(c) + else: + c.__count += 1 + work(c) - finally: - os._exit(0) + os._exit(0) if __name__ == "__main__": main() === StandaloneZODB/ZEO/tests/testZEO.py 1.21 => 1.21.2.1 === # ############################################################################## - """Test suite for ZEO based on ZODB.tests""" import asyncore @@ -27,6 +26,8 @@ import ZEO.ClientStorage, ZEO.StorageServer import ThreadedAsync, ZEO.trigger from ZODB.FileStorage import FileStorage +from ZODB.TimeStamp import TimeStamp +from ZODB.Transaction import Transaction import thread from ZEO.tests import forker, Cache @@ -35,7 +36,7 @@ # Sorry Jim... from ZODB.tests import StorageTestBase, BasicStorage, VersionStorage, \ TransactionalUndoStorage, TransactionalUndoVersionStorage, \ - PackableStorage, Synchronization, ConflictResolution, RevisionStorage + PackableStorage, Synchronization, ConflictResolution from ZODB.tests.MinPO import MinPO from ZODB.tests.StorageTestBase import zodb_unpickle @@ -56,9 +57,63 @@ self.storage.pack(t, f, wait=1) class ZEOTestBase(StorageTestBase.StorageTestBase): - """Version of the storage test class that supports ZEO.""" - pass + """Version of the storage test class that supports ZEO. + + For ZEO, we don't always get the serialno/exception for a + particular store as the return value from the store. But we + will get no later than the return value from vote. + """ + def _dostore(self, oid=None, revid=None, data=None, version=None, + already_pickled=0): + """Do a complete storage transaction. + + The defaults are: + - oid=None, ask the storage for a new oid + - revid=None, use a revid of ZERO + - data=None, pickle up some arbitrary data (the integer 7) + - version=None, use the empty string version + + Returns the object's new revision id. + """ + if oid is None: + oid = self._storage.new_oid() + if revid is None: + revid = ZERO + if data is None: + data = MinPO(7) + if not already_pickled: + data = StorageTestBase.zodb_pickle(data) + if version is None: + version = '' + # Begin the transaction + t = Transaction() + self._storage.tpc_begin(t) + # Store an object + r1 = self._storage.store(oid, revid, data, version, t) + s1 = self._get_serial(r1) + # Finish the transaction + r2 = self._storage.tpc_vote(t) + s2 = self._get_serial(r2) + self._storage.tpc_finish(t) + # s1, s2 can be None or dict + assert not (s1 and s2) + return s1 and s1[oid] or s2 and s2[oid] + + def _get_serial(self, r): + """Return oid -> serialno dict from sequence of ZEO replies.""" + d = {} + if r is None: + return None + if type(r) == types.StringType: + raise RuntimeError, "unexpected ZEO response: no oid" + else: + for oid, serial in r: + if isinstance(serial, Exception): + raise serial + d[oid] = serial + return d + # Some of the ZEO tests depend on the version of FileStorage available # for the tests. If we run these tests using Zope 2.3, FileStorage # doesn't support TransactionalUndo. @@ -75,14 +130,13 @@ else: class VersionDependentTests: pass - + class GenericTests(ZEOTestBase, VersionDependentTests, Cache.StorageWithCache, Cache.TransUndoStorageWithCache, BasicStorage.BasicStorage, VersionStorage.VersionStorage, - RevisionStorage.RevisionStorage, PackableStorage.PackableStorage, Synchronization.SynchronizedStorage, ): @@ -94,12 +148,16 @@ returns a specific storage, e.g. FileStorage. """ + __super_setUp = StorageTestBase.StorageTestBase.setUp + __super_tearDown = StorageTestBase.StorageTestBase.tearDown + def setUp(self): """Start a ZEO server using a Unix domain socket The ZEO server uses the storage object returned by the getStorage() method. """ + self.__super_setUp() self.running = 1 client, exit, pid = forker.start_zeo(self.getStorage()) self._pid = pid @@ -114,13 +172,68 @@ self._server.close() os.waitpid(self._pid, 0) self.delStorage() + self.__super_tearDown() + + def checkTwoArgBegin(self): + # XXX ZEO doesn't support 2-arg begin + pass def checkLargeUpdate(self): obj = MinPO("X" * (10 * 128 * 1024)) self._dostore(data=obj) - def checkTwoArgBegin(self): - pass # ZEO 1 doesn't support two-arg begin + def checkCommitLockOnCommit(self): + self._checkCommitLock("tpc_finish") + + def checkCommitLockOnAbort(self): + self._checkCommitLock("tpc_abort") + + def _checkCommitLock(self, method_name): + # check the commit lock when a client attemps a transaction, + # but fails/exits before finishing the commit. + + # Start on transaction normally. + t = Transaction() + self._storage.tpc_begin(t) + + # Start a second transaction on a different connection without + # blocking the test thread. + self._storages = [] + for i in range(3): + storage2 = self._duplicate_client() + t2 = Transaction() + tid = self._get_timestamp() + storage2._call.sendMessage('tpc_begin_sync', + tid, t2.user, t2.description, + t2._extension) + if i == 0: + storage2.close() + else: + self._storages.append((storage2, t2)) + + oid = self._storage.new_oid() + self._storage.store(oid, None, '', '', t) + self._storage.tpc_vote(t) + self._storage.tpc_finish(t) + + for store, trans in self._storages: + store.tpc_abort(trans) + store.close() + + # Make sure the server is still responsive + self._dostore() + + def _duplicate_client(self): + "Open another ClientStorage to the same server." + addr = self._storage._connection + new = ZEO.ClientStorage.ClientStorage(addr) + new.registerDB(DummyDB(), None) + return new + + def _get_timestamp(self): + t = time.time() + t = apply(TimeStamp,(time.gmtime(t)[:5]+(t%60,))) + return 't' class ZEOFileStorageTests(GenericTests): __super_setUp = GenericTests.setUp @@ -148,8 +261,11 @@ can't be created in the parent process and passed to the child. All the work has to be done in the server's process. """ + __super_setUp = StorageTestBase.StorageTestBase.setUp + __super_tearDown = StorageTestBase.StorageTestBase.tearDown def setUp(self): + self.__super_setUp() args = self.getStorageInfo() name = args[0] args = args[1:] @@ -169,6 +285,7 @@ ## os.waitpid(self.test_pid, 0) time.sleep(0.5) self.delStorage() + self.__super_tearDown() class WindowsZEOFileStorageTests(WindowsGenericTests): @@ -192,6 +309,8 @@ start and stop a ZEO storage server. """ + __super_tearDown = StorageTestBase.StorageTestBase.tearDown + ports = [] for i in range(200): ports.append(random.randrange(25000, 30000)) @@ -207,7 +326,6 @@ def tearDown(self): """Try to cause the tests to halt""" - self._storage.close() self.shutdownServer() # file storage appears to create four files for ext in '', '.index', '.lock', '.tmp': @@ -218,6 +336,7 @@ path = "c1-test-%d.zec" % i if os.path.exists(path): os.unlink(path) + self.__super_tearDown() def checkBasicPersistence(self): """Verify cached data persists across client storage instances. === StandaloneZODB/ZEO/tests/winserver.py 1.3 => 1.3.2.1 === # ############################################################################## - """Helper file used to launch ZEO server for Windows tests""" import asyncore From jeremy at zope.com Fri Mar 15 01:45:22 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - logger.py:1.1.2.1 Message-ID: <200203150645.g2F6jMi18438@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv18417 Added Files: Tag: zeo-1_0-debug-branch logger.py Log Message: Add simplified logging mechanism. === Added File StandaloneZODB/ZEO/logger.py === import string from types import StringType from zLOG import * __all__ = ["zLogger", "format_msg"] _MAX_MSG_SIZE = 120 def format_msg(*args): accum = [] total_len = 0 for arg in args: if not isinstance(arg, StringType): arg = str(arg) accum.append(arg) total_len = total_len + len(arg) if total_len >= _MAX_MSG_SIZE: break m = string.join(accum) if len(m) > _MAX_MSG_SIZE: m = m[:_MAX_MSG_SIZE] + ' ...' return m class zLogger: def __init__(self, channel): self.channel = channel def __str__(self): raise RuntimeError, "don't print me" def trace(self, msg): LOG(self.channel, TRACE, msg) def debug(self, msg): LOG(self.channel, DEBUG, msg) def blather(self, msg): LOG(self.channel, BLATHER, msg) def info(self, msg): LOG(self.channel, INFO, msg) def problem(self, msg): LOG(self.channel, PROBLEM, msg) def warning(self, msg): LOG(self.channel, WARNING, msg) def error(self, msg, error=None): LOG(self.channel, ERROR, msg, error=error) def panic(self, msg): LOG(self.channel, PANIC, msg) From jeremy at zope.com Fri Mar 15 01:47:53 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - ClientStorage.py:1.38.2.2 StorageServer.py:1.34.2.2 smac.py:1.14.2.2 zrpc.py:1.21.2.2 Message-ID: <200203150647.g2F6lr118649@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv18632 Modified Files: Tag: zeo-1_0-debug-branch ClientStorage.py StorageServer.py smac.py zrpc.py Log Message: Revised logging that is performed. Try to use log levels consistently. The lowest level, TRACE, is used to prints per-message dumps and nothing else. The next level, DEBUG, is use to print method calls and responses, plus some other cruft. Add status() call to client and server. The status() implementation lives in the StorageServer instance. It prints a log message with a list of all storages and all connections. === StandaloneZODB/ZEO/ClientStorage.py 1.38.2.1 => 1.38.2.2 === __version__='$Revision$'[11:-2] -import struct, time, os, socket, string, Sync, zrpc, ClientCache -import tempfile, Invalidator, ExtensionClass, thread -import ThreadedAsync - -now=time.time +import struct, time, os, socket, string +import tempfile, thread from struct import pack, unpack +from types import TupleType + +import Invalidator, ExtensionClass +import ThreadedAsync, Sync, zrpc, ClientCache + from ZODB import POSException, BaseStorage from ZODB.TimeStamp import TimeStamp -from zLOG import LOG, PROBLEM, INFO -try: from ZODB.ConflictResolution import ResolvedSerial -except: ResolvedSerial='rs' +from ZEO.logger import zLogger + +log = zLogger("ZEO Client") -TupleType=type(()) +try: + from ZODB.ConflictResolution import ResolvedSerial +except: + ResolvedSerial='rs' class ClientStorageError(POSException.StorageError): """An error occured in the ZEO Client Storage""" @@ -62,8 +67,12 @@ self._info={'length': 0, 'size': 0, 'name': 'ZEO Client', 'supportsUndo':0, 'supportsVersions': 0, } - - self._call=zrpc.asyncRPC(connection, debug=debug, + + if debug: + debug_log = log + else: + debug_log = None + self._call=zrpc.asyncRPC(connection, debug=debug_log, tmin=min_disconnect_poll, tmax=max_disconnect_poll) @@ -132,7 +141,7 @@ # If we can't connect right away, go ahead and open the cache # and start a separate thread to try and reconnect. - LOG("ClientStorage", PROBLEM, "Failed to connect to storage") + log.problem("Failed to connect to storage") self._cache.open() thread.start_new_thread(self._call.connect,(0,)) @@ -140,7 +149,7 @@ # notifyConnected def notifyConnected(self, s): - LOG("ClientStorage", INFO, "Connected to storage") + log.info("Connected to storage") self._lock_acquire() try: @@ -197,7 +206,7 @@ ### responsible for starting the thread that makes the connection. def notifyDisconnected(self, ignored): - LOG("ClientStorage", PROBLEM, "Disconnected from storage") + log.problem("Disconnected from storage") self._connected=0 self._transaction=None thread.start_new_thread(self._call.connect,(0,)) @@ -233,7 +242,7 @@ def close(self): self._lock_acquire() try: - LOG("ClientStorage", INFO, "close") + log.info("close") self._call.closeIntensionally() try: self._tfile.close() @@ -549,6 +558,9 @@ finally: self._lock_release() def sync(self): self._call.sync() + + def status(self): + self._call.sendMessage('status') def getWakeup(_w=[]): if _w: return _w[0] === StandaloneZODB/ZEO/StorageServer.py 1.34.2.1 => 1.34.2.2 === import asyncore, socket, string, sys, os -from smac import SizedMessageAsyncConnection -from ZODB import POSException import cPickle from cPickle import Unpickler +from cStringIO import StringIO +from thread import start_new_thread +from types import StringType + +from ZODB import POSException from ZODB.POSException import TransactionError, UndoError, VersionCommitError from ZODB.Transaction import Transaction -import traceback -from zLOG import LOG, INFO, ERROR, TRACE, BLATHER from ZODB.referencesf import referencesf -from thread import start_new_thread -from cStringIO import StringIO + from ZEO import trigger from ZEO import asyncwrap -from ZEO.smac import Disconnected -from types import StringType - -class StorageServerError(POSException.StorageError): pass - -max_blather=120 -def blather(*args): - accum = [] - total_len = 0 - for arg in args: - if not isinstance(arg, StringType): - arg = str(arg) - accum.append(arg) - total_len = total_len + len(arg) - if total_len >= max_blather: - break - m = string.join(accum) - if len(m) > max_blather: m = m[:max_blather] + ' ...' - LOG('ZEO Server', TRACE, m) +from ZEO.smac import Disconnected, SizedMessageAsyncConnection +from ZEO.logger import zLogger, format_msg +class StorageServerError(POSException.StorageError): + pass # We create a special fast pickler! This allows us # to create slightly more efficient pickles and @@ -56,6 +41,8 @@ pickler.fast=1 # Don't use the memo dump=pickler.dump +log = zLogger("ZEO Server") + class StorageServer(asyncore.dispatcher): def __init__(self, connection, storages): @@ -80,14 +67,14 @@ self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() - LOG('ZEO Server', INFO, 'Listening on %s' % repr(connection)) + log.info('Listening on %s' % repr(connection)) self.bind(connection) self.listen(5) def register_connection(self, connection, storage_id): storage=self.__storages.get(storage_id, None) if storage is None: - LOG('ZEO Server', ERROR, "Unknown storage_id: %s" % storage_id) + log.error("Unknown storage_id: %s" % storage_id) connection.close() return None, None @@ -132,12 +119,17 @@ else: ZEOConnection(self, sock, addr) - def log_info(self, message, type='info'): - if type=='error': type=ERROR - else: type=INFO - LOG('ZEO Server', type, message) + def status(self): + """Log status information about connections and storages""" - log=log_info + lines = [] + for storage_id, connections in self.__connections.items(): + s = "Storage %s has %d connections" % (storage_id, + len(connections)) + lines.append(s) + for c in connections: + lines.append(str(c)) + log.info(string.join(lines, "\n")) storage_methods={} for n in ( @@ -148,6 +140,7 @@ 'tpc_finish', 'undo', 'undoLog', 'undoInfo', 'versionEmpty', 'versions', 'transactionalUndo', 'vote', 'zeoLoad', 'zeoVerify', 'beginZeoVerify', 'endZeoVerify', + 'status' ): storage_methods[n]=1 storage_method=storage_methods.has_key @@ -159,7 +152,8 @@ raise StorageServerError, ( "Couldn\'t import global module %s" % module) - try: r=getattr(m, name) + try: + r=getattr(m, name) except: raise StorageServerError, ( "Couldn\'t find global %s in module %s" % (name, module)) @@ -177,12 +171,21 @@ def __init__(self, server, sock, addr): self.__server=server + self.status = server.status self.__invalidated=[] self.__closed=None - if __debug__: debug='ZEO Server' - else: debug=0 + if __debug__: + debug = log + else: + debug = None SizedMessageAsyncConnection.__init__(self, sock, addr, debug=debug) - LOG('ZEO Server', INFO, 'Connect %s %s' % (id(self), `addr`)) + log.info('Connect %s %s' % (id(self), `addr`)) + + def __repr__(self): + return "' or 'closed>')) def close(self): t=self._transaction @@ -196,17 +199,17 @@ self.__server.unregister_connection(self, self.__storage_id) self.__closed=1 SizedMessageAsyncConnection.close(self) - LOG('ZEO Server', INFO, 'Close %s' % id(self)) + log.info('Close %s' % id(self)) def message_input(self, message, dump=dump, Unpickler=Unpickler, StringIO=StringIO, None=None): if __debug__: - if len(message) > max_blather: - tmp = `message[:max_blather]` + if len(message) > 120: # XXX need constant from logger + tmp = `message[:120]` else: tmp = `message` - blather('message_input', id(self), tmp) + log.trace("message_input %s" % tmp) if self.__storage is None: # This is the first communication from the client @@ -226,27 +229,31 @@ name, args = args[0], args[1:] if __debug__: - apply(blather, - ("call", id(self), ":", name,) + args) + log.debug("call %s%s from %s" % (name, format_msg(args), + self.addr)) if not storage_method(name): + log.warning("Invalid method name: %s" % name) raise 'Invalid Method Name', name if hasattr(self, name): r=apply(getattr(self, name), args) else: r=apply(getattr(self.__storage, name), args) - if r is _noreturn: return + if r is _noreturn: + if __debug__: + log.trace("no return to %s" % `self.addr`) + return except (UndoError, VersionCommitError): # These are normal usage errors. No need to leg them self.return_error(sys.exc_info()[0], sys.exc_info()[1]) return except: - LOG('ZEO Server', ERROR, 'error', error=sys.exc_info()) + log.error("error", error=sys.exc_info()) self.return_error(sys.exc_info()[0], sys.exc_info()[1]) return if __debug__: - blather("%s R: %s" % (id(self), `r`)) + log.trace("return %s to %s" % (`r`, self.addr)) r=dump(r,1) self.message_output('R'+r) @@ -256,7 +263,7 @@ err_value = err_type, err_value if __debug__: - blather("%s E: %s" % (id(self), `err_value`)) + log.trace("%s E: %s" % (id(self), `err_value`)) try: r=dump(err_value, 1) except: @@ -340,11 +347,11 @@ def _pack(self, t, wait=0): try: - LOG('ZEO Server', BLATHER, 'pack begin') + log.blather('pack begin') self.__storage.pack(t, referencesf) - LOG('ZEO Server', BLATHER, 'pack end') + log.blather('pack end') except: - LOG('ZEO Server', ERROR, + log.error( 'Pack failed for %s' % self.__storage_id, error=sys.exc_info()) if wait: @@ -396,7 +403,7 @@ # all errors need to be serialized to prevent unexpected # returns, which would screw up the return handling. # IOW, Anything that ends up here is evil enough to be logged. - LOG('ZEO Server', ERROR, 'store error', error=sys.exc_info()) + log.error('store error', error=sys.exc_info()) newserial=sys.exc_info()[1] else: if serial != '\0\0\0\0\0\0\0\0': @@ -471,7 +478,7 @@ # disconnect will have generated its own log event. onerror() except: - LOG('ZEO Server', ERROR, + log.error( "Unexpected error handling queued tpc_begin()", error=sys.exc_info()) onerror() @@ -564,7 +571,7 @@ if __name__=='__main__': import ZODB.FileStorage name, port = sys.argv[1:3] - blather(name, port) + log.trace(format_msg(name, port)) try: port='', int(port) except: === StandaloneZODB/ZEO/smac.py 1.14.2.1 => 1.14.2.2 === import asyncore, string, struct, zLOG, sys, Acquisition import socket, errno -from zLOG import LOG, TRACE, ERROR, INFO +from logger import zLogger # Use the dictionary to make sure we get the minimum number of errno # entries. We expect that EWOULDBLOCK == EAGAIN on most systems -- @@ -49,9 +49,9 @@ '__init__')(self, sock, map) self.addr=addr if debug is not None: - self._debug=debug + self._debug = debug elif not hasattr(self, '_debug'): - self._debug=__debug__ and 'smac' + self._debug = __debug__ and zLogger("smac") self.__state=None self.__inp=None self.__inpl=0 @@ -132,23 +132,18 @@ def message_output(self, message, pack=struct.pack, len=len): - if self._debug: - if len(message) > 40: m=message[:40]+' ...' - else: m=message - LOG(self._debug, TRACE, 'message_output %s' % `m`) + if self._debug is not None: + if len(message) > 40: + m = message[:40]+' ...' + else: + m = message + self._debug.trace('message_output %s' % `m`) append=self.__append if append is None: raise Disconnected("This action is temporarily unavailable.

") append(pack(">i",len(message))+message) - - def log_info(self, message, type='info'): - if type=='error': type=ERROR - else: type=INFO - LOG('ZEO', type, message) - - log=log_info def close(self): if self.__append is not None: === StandaloneZODB/ZEO/zrpc.py 1.21.2.1 => 1.21.2.2 === self.__call_lr=l.release - def connect(self, tryonce=1, log_type='client'): + def connect(self, tryonce=1): t=self._tmin connection = self._connection debug=self._debug while self.__closed == 0: - if log_type: LOG(log_type, INFO, - 'Trying to connect to server: %s' % `connection`) + LOG("client", INFO, + 'Trying to connect to server: %s' % `connection`) try: if type(connection) is type(''): s=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -75,15 +75,15 @@ s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(connection) except Exception, err: - if debug: - LOG(debug, DEBUG, "Failed to connect to server: %s" % err) + if debug is not None: + debug.blather("Failed to connect to server: %s" % err) if tryonce: return 0 time.sleep(t) t=t*2 if t > self._tmax: t=self._tmax else: - if debug: - LOG(debug, DEBUG, "Connected to server") + if debug is not None: + debug.blather("Connected to server") # Make sure the result lock is set, se we don't # get an old result (e.g. the exception that @@ -199,12 +199,12 @@ self._outOfBand=f def message_input(self, m): - if self._debug: + if self._debug is not None: if len(m) > 60: md = repr(m[:60]) + ' ...' else: md = repr(m) - LOG(self._debug, TRACE, 'message_input %s' % md) + self._debug.trace('message_input %s' % md) c=m[:1] if c in 'RE': From jeremy at zope.com Fri Mar 15 01:58:05 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.34.2.3 Message-ID: <200203150658.g2F6w5Z21214@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv21203 Modified Files: Tag: zeo-1_0-debug-branch StorageServer.py Log Message: log info about distribution commit lock. Log messages when a client is added to the waiting list and when it is removed. === StandaloneZODB/ZEO/StorageServer.py 1.34.2.2 => 1.34.2.3 === # sort of messy way to add tag 'closed' to # connections that are closed - (self.__closed is None and '>' or 'closed>')) + (self.__closed is None and '>' or ' closed>')) def close(self): t=self._transaction @@ -464,11 +464,15 @@ def commitlock_suspend(self, resume, args, onerror): self.__storage._waiting.append((resume, args, onerror)) + log.blather("suspend %s. %d queued clients" % (resume.im_self, + len(self.__storage._waiting))) def commitlock_resume(self): waiting = self.__storage._waiting while waiting: resume, args, onerror = waiting.pop(0) + log.blather("resuming queued client %s, %d still queued" % ( + resume.im_self, len(waiting))) try: if apply(resume, args): break From jeremy at zope.com Fri Mar 15 02:01:59 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - asyncwrap.py:1.3.2.2 Message-ID: <200203150701.g2F71xP22358@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv22321 Modified Files: Tag: zeo-1_0-debug-branch asyncwrap.py Log Message: Current implemenation does not require Python 2.0. === StandaloneZODB/ZEO/asyncwrap.py 1.3.2.1 => 1.3.2.2 === """ -# XXX The current implementation requires Python 2.0. Not sure if -# that's acceptable, depends on how many users want to combine ZEO 1.0 -# and Zope 2.3. - import asyncore import errno import select From jeremy at zope.com Fri Mar 15 02:30:42 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.34.2.4 Message-ID: <200203150730.g2F7UgI29737@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv29726 Modified Files: Tag: zeo-1_0-debug-branch StorageServer.py Log Message: Extend status() with last method status and asyncore status. For each active connection, log the last method that was invoked, the time it was invoked, and the time it returned. Also, log whether asyncore thinks the connection is readable or writable. === StandaloneZODB/ZEO/StorageServer.py 1.34.2.3 => 1.34.2.4 === from cStringIO import StringIO from thread import start_new_thread +import time from types import StringType from ZODB import POSException @@ -128,7 +129,9 @@ len(connections)) lines.append(s) for c in connections: - lines.append(str(c)) + lines.append("%s readable=%s writeable=%s" % ( + c, c.readable(), c.writable())) + lines.append("\t" + c.stats()) log.info(string.join(lines, "\n")) storage_methods={} @@ -178,9 +181,36 @@ debug = log else: debug = None + + if __debug__: + # store some detailed statistics about method calls + self._last_method = None + self._t_begin = None + self._t_end = None + SizedMessageAsyncConnection.__init__(self, sock, addr, debug=debug) log.info('Connect %s %s' % (id(self), `addr`)) + def stats(self): + # This method is called via the status() command. The stats + # are of limited use for the current command, because the + # actual invocation of status() will clobber the previous + # method's statistics. + # + # When there are multiple connections active, a new connection + # can always get detailed statistics about other connections. + if __debug__: + if self._last_method == "status": + return "method=status begin=%s end=..." % self._t_begin + if self._t_end is not None and self._t_begin is not None: + delta = self._t_end - self._t_begin + else: + delta = -1 + return "method=%s begin=%s end=%s delta=%.3f" % ( + self._last_method, self._t_begin, self._t_end, delta) + else: + return "" + def __repr__(self): return " 120: # XXX need constant from logger tmp = `message[:120]` else: @@ -212,6 +246,9 @@ log.trace("message_input %s" % tmp) if self.__storage is None: + if __debug__: + log.debug("register connection to %s from %s" % (message, + self.addr)) # This is the first communication from the client self.__storage, self.__storage_id = ( self.__server.register_connection(self, message)) @@ -229,11 +266,14 @@ name, args = args[0], args[1:] if __debug__: + self._last_method = name log.debug("call %s%s from %s" % (name, format_msg(args), self.addr)) if not storage_method(name): log.warning("Invalid method name: %s" % name) + if __debug__: + self._t_end = time.time() raise 'Invalid Method Name', name if hasattr(self, name): r=apply(getattr(self, name), args) @@ -241,19 +281,26 @@ r=apply(getattr(self.__storage, name), args) if r is _noreturn: if __debug__: - log.trace("no return to %s" % `self.addr`) + log.debug("no return to %s" % `self.addr`) + self._t_end = time.time() return - except (UndoError, VersionCommitError): - # These are normal usage errors. No need to leg them + except (UndoError, VersionCommitError), err: + if __debug__: + log.debug("return error %s to %s" % (err, self.addr)) + self._t_end = time.time() + # These are normal usage errors. No need to log them. self.return_error(sys.exc_info()[0], sys.exc_info()[1]) return except: + if __debug__: + self._t_end = time.time() log.error("error", error=sys.exc_info()) self.return_error(sys.exc_info()[0], sys.exc_info()[1]) return if __debug__: - log.trace("return %s to %s" % (`r`, self.addr)) + log.debug("return %s to %s" % (format_msg(r), self.addr)) + self._t_end = time.time() r=dump(r,1) self.message_output('R'+r) From jeremy at zope.com Fri Mar 15 02:50:01 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.34.2.5 Message-ID: <200203150750.g2F7o1C01382@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv1307 Modified Files: Tag: zeo-1_0-debug-branch StorageServer.py Log Message: Add number of calls made to stats. === StandaloneZODB/ZEO/StorageServer.py 1.34.2.4 => 1.34.2.5 === self._t_begin = None self._t_end = None + self._ncalls = 0 SizedMessageAsyncConnection.__init__(self, sock, addr, debug=debug) log.info('Connect %s %s' % (id(self), `addr`)) @@ -201,13 +202,15 @@ # can always get detailed statistics about other connections. if __debug__: if self._last_method == "status": - return "method=status begin=%s end=..." % self._t_begin + return "method=status begin=%s end=... ncalls=%d" % ( + self._t_begin, self._ncalls) if self._t_end is not None and self._t_begin is not None: delta = self._t_end - self._t_begin else: delta = -1 - return "method=%s begin=%s end=%s delta=%.3f" % ( - self._last_method, self._t_begin, self._t_end, delta) + return "method=%s begin=%s end=%s delta=%.3f ncalls=%d" % ( + self._last_method, self._t_begin, self._t_end, delta, + self._ncalls) else: return "" @@ -267,6 +270,7 @@ name, args = args[0], args[1:] if __debug__: self._last_method = name + self._ncalls = self._ncalls + 1 log.debug("call %s%s from %s" % (name, format_msg(args), self.addr)) From shane at cvs.zope.org Mon Mar 25 16:54:30 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO/zrpc - client.py:1.1.2.14 Message-ID: <200203252154.g2PLsUW07334@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO/zrpc In directory cvs.zope.org:/tmp/cvs-serv7249 Modified Files: Tag: Standby-branch client.py Log Message: Fixed race condition: if the storage server connected very quickly, the one_attempt event never got set, which froze startup. === ZEO/ZEO/zrpc/client.py 1.1.2.13 => 1.1.2.14 === def run(self): delay = self.tmin - while not (self.stopped or self.attempt_connects()): + while not self.stopped: + success = self.attempt_connects() if not self.one_attempt.isSet(): self.one_attempt.set() + if success: + break time.sleep(delay) delay *= 2 if delay > self.tmax: From jeremy at zope.com Tue Mar 26 00:52:07 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO/tests - testZEO.py:1.21.2.2 Message-ID: <200203260552.g2Q5q7T21059@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO/tests In directory cvs.zope.org:/tmp/cvs-serv21048 Modified Files: Tag: zeo-1_0-debug-branch testZEO.py Log Message: Fix bogus get_timestamp() method. Return `t` not 't'!!! Add a couple of calls to status() to make sure it works. === StandaloneZODB/ZEO/tests/testZEO.py 1.21.2.1 => 1.21.2.2 === """Try to cause the tests to halt""" self.running = 0 + self._storage.status() self._storage.close() self._server.close() os.waitpid(self._pid, 0) @@ -214,6 +215,7 @@ oid = self._storage.new_oid() self._storage.store(oid, None, '', '', t) self._storage.tpc_vote(t) + self._storage.status() self._storage.tpc_finish(t) for store, trans in self._storages: @@ -233,7 +235,7 @@ def _get_timestamp(self): t = time.time() t = apply(TimeStamp,(time.gmtime(t)[:5]+(t%60,))) - return 't' + return `t` class ZEOFileStorageTests(GenericTests): __super_setUp = GenericTests.setUp From jeremy at zope.com Tue Mar 26 00:59:10 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.34.2.6 smac.py:1.14.2.3 Message-ID: <200203260559.g2Q5xAK22470@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv22457 Modified Files: Tag: zeo-1_0-debug-branch StorageServer.py smac.py Log Message: Add per-method logging for some methods at blather level. This logging is less verbose than the debug level logging, but still notes all transactions boundaries, loads, and stores. Format oids and txnids using ZODB.utils.U64 for easier reading. XXX There seems to be an intermittent error in this branch w/ python -O! Perhaps once every four test runs I see the checkCommitLockOnAbort test fail with a release unlocked lock error raised on the server side. The terse asyncore exception points to message_input() line 201. Not sure if this is on the client side or the server side. Assume it must be the client, since the server doesn't get returns. The client-side traceback is in a tpc_finish() / __call__() of zrpc with the std "see server log for real traceback" method. But the server log doesn't have anything! === StandaloneZODB/ZEO/StorageServer.py 1.34.2.5 => 1.34.2.6 === from ZODB.Transaction import Transaction from ZODB.referencesf import referencesf +from ZODB.utils import U64 from ZEO import trigger from ZEO import asyncwrap @@ -190,7 +191,8 @@ self._ncalls = 0 SizedMessageAsyncConnection.__init__(self, sock, addr, debug=debug) - log.info('Connect %s %s' % (id(self), `addr`)) + self.logaddr = repr(addr) # form of addr suitable for logging + log.info('Connect %s %s' % (id(self), self.logaddr)) def stats(self): # This method is called via the status() command. The stats @@ -250,8 +252,8 @@ if self.__storage is None: if __debug__: - log.debug("register connection to %s from %s" % (message, - self.addr)) + log.blather("register connection to %s from %s" % (message, + self.logaddr)) # This is the first communication from the client self.__storage, self.__storage_id = ( self.__server.register_connection(self, message)) @@ -272,7 +274,7 @@ self._last_method = name self._ncalls = self._ncalls + 1 log.debug("call %s%s from %s" % (name, format_msg(args), - self.addr)) + self.logaddr)) if not storage_method(name): log.warning("Invalid method name: %s" % name) @@ -285,12 +287,12 @@ r=apply(getattr(self.__storage, name), args) if r is _noreturn: if __debug__: - log.debug("no return to %s" % `self.addr`) + log.debug("no return to %s" % self.logaddr) self._t_end = time.time() return except (UndoError, VersionCommitError), err: if __debug__: - log.debug("return error %s to %s" % (err, self.addr)) + log.debug("return error %s to %s" % (err, self.logaddr)) self._t_end = time.time() # These are normal usage errors. No need to log them. self.return_error(sys.exc_info()[0], sys.exc_info()[1]) @@ -303,7 +305,7 @@ return if __debug__: - log.debug("return %s to %s" % (format_msg(r), self.addr)) + log.debug("return %s to %s" % (format_msg(r), self.logaddr)) self._t_end = time.time() r=dump(r,1) @@ -350,6 +352,8 @@ } def zeoLoad(self, oid): + if __debug__: + log.blather("zeoLoad(%s) %s" % (U64(oid), self.logaddr)) storage=self.__storage v=storage.modifiedInVersion(oid) if v: pv, sv = storage.load(oid, v) @@ -366,6 +370,8 @@ def beginZeoVerify(self): + if __debug__: + log.blather("beginZeoVerify() %s" % self.logaddr) self.message_output('bN.') return _noreturn @@ -382,6 +388,8 @@ return _noreturn def endZeoVerify(self): + if __debug__: + log.blather("endZeoVerify() %s" % self.logaddr) self.message_output('eN.') return _noreturn @@ -439,6 +447,9 @@ def storea(self, oid, serial, data, version, id, dump=dump): + if __debug__: + log.blather("storea(%s, [%d], %s) %s" % (U64(oid), len(data), + U64(id), self.logaddr)) try: t=self._transaction if t is None or id != t.id: @@ -478,12 +489,17 @@ return self.__storage.tpc_vote(t) def transactionalUndo(self, trans_id, id): + if __debug__: + log.blather("transactionalUndo(%s, %s) %s" % (trans_id, + U64(id), self.logaddr)) t=self._transaction if t is None or id != t.id: raise POSException.StorageTransactionError(self, id) return self.__storage.transactionalUndo(trans_id, self._transaction) def undo(self, transaction_id): + if __debug__: + log.blather("undo(%s) %s" % (transaction_id, self.logaddr)) oids=self.__storage.undo(transaction_id) if oids: self.__server.invalidate( @@ -539,6 +555,12 @@ onerror() def tpc_abort(self, id): + if __debug__: + try: + log.blather("tpc_abort(%s) %s" % (U64(id), self.logaddr)) + except: + print repr(id) + raise t = self._transaction if t is None or id != t.id: return @@ -554,6 +576,8 @@ self.message_output('UN.') def tpc_begin(self, id, user, description, ext): + if __debug__: + log.blather("tpc_begin(%s) %s" % (U64(id), self.logaddr)) t = self._transaction if t is not None: if id == t.id: @@ -567,7 +591,8 @@ if storage._transaction is not None: self.commitlock_suspend(self.unlock, (), self.close) return 1 # Return a flag indicating a lock condition. - + + assert id != 't' self._transaction=t=Transaction() t.id=id t.user=user @@ -604,6 +629,8 @@ return 1 def tpc_finish(self, id, user, description, ext): + if __debug__: + log.blather("tpc_finish(%s) %s" % (U64(id), self.logaddr)) t = self._transaction if id != t.id: return === StandaloneZODB/ZEO/smac.py 1.14.2.2 => 1.14.2.3 === '__init__')(self, sock, map) self.addr=addr - if debug is not None: + if debug is None and __debug__: + self._debug = zLogger("smac") + else: self._debug = debug - elif not hasattr(self, '_debug'): - self._debug = __debug__ and zLogger("smac") self.__state=None self.__inp=None self.__inpl=0 From jeremy at zope.com Tue Mar 26 14:32:24 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:19 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - zrpc.py:NONE Message-ID: <200203261932.g2QJWO211992@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv10895 Removed Files: Tag: Standby-branch zrpc.py Log Message: I thought this file was already removed! === Removed File ZEO/ZEO/zrpc.py === From shane at cvs.zope.org Tue Mar 26 15:17:58 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - StorageServer.py:1.32.6.7 Message-ID: <200203262017.g2QKHwu23357@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv23346 Modified Files: Tag: Standby-branch StorageServer.py Log Message: Corrected call to self._log() === ZEO/ZEO/StorageServer.py 1.32.6.6 => 1.32.6.7 === self.__storage.pack(t, referencesf) except: - self._log('ZEO Server', zLOG.ERROR, - 'Pack failed for %s' % self.__storage_id, + self._log('Pack failed for %s' % self.__storage_id, + zLOG.ERROR, error=sys.exc_info()) if wait: raise From shane at cvs.zope.org Wed Mar 27 15:13:37 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - ClientStorage.py:1.35.6.9 Message-ID: <200203272013.g2RKDbc13019@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv12931 Modified Files: Tag: Standby-branch ClientStorage.py Log Message: Corrected an omission: The client has to get the information about what the server supports. This fixes transactional undo. === ZEO/ZEO/ClientStorage.py 1.35.6.8 => 1.35.6.9 === # would start faster. stub.register(str(self._storage), self._is_read_only) + self._info.update(stub.get_info()) self.verify_cache(stub) # Don't make the server available to clients until after From shane at cvs.zope.org Wed Mar 27 18:35:58 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - ClientStorage.py:1.35.6.10 Message-ID: <200203272335.g2RNZwP28986@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv28902 Modified Files: Tag: Standby-branch ClientStorage.py Log Message: Show how the connection was made in the log file === ZEO/ZEO/ClientStorage.py 1.35.6.9 => 1.35.6.10 === def notifyConnected(self, c): - log2(INFO, "Connected to storage") + log2(INFO, "Connected to storage via %s" % repr(c)) stub = ServerStub.StorageServer(c) self._oids = [] From shane at cvs.zope.org Thu Mar 28 12:25:21 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - StorageServer.py:1.32.6.8 Message-ID: <200203281725.g2SHPLT05066@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv5055 Modified Files: Tag: Standby-branch StorageServer.py Log Message: Invalidations may occur before any connections are made, so the invalidate() method has to be ready for this situation. === ZEO/ZEO/StorageServer.py 1.32.6.7 => 1.32.6.8 === def invalidate(self, conn, storage_id, invalidated=(), info=0): - for p in self.connections[storage_id]: + for p in self.connections.get(storage_id, ()): if invalidated and p is not conn: p.client.Invalidate(invalidated) else: From shane at cvs.zope.org Thu Mar 28 12:25:54 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO/zrpc - connection.py:1.1.2.7 Message-ID: <200203281725.g2SHPsH05454@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO/zrpc In directory cvs.zope.org:/tmp/cvs-serv5073/zrpc Modified Files: Tag: Standby-branch connection.py Log Message: Allow the server to initiate messages to clients. === ZEO/ZEO/zrpc/connection.py 1.1.2.6 => 1.1.2.7 === class ServerConnection(Connection): + """Connection on the server side""" + # XXX Do we need this class anymore? - def _do_async_poll(self, wait=0): - """If this is a server, there is no explicit IO to do""" - pass - - def set_async(self, map): - pass - - # XXX _do_async_loop is never called. Should it be defined as - # above anyway? class ManagedServerConnection(ServerConnection): """A connection that notifies its ConnectionManager of closing""" From shane at cvs.zope.org Thu Mar 28 13:30:16 2002 From: shane at cvs.zope.org (Shane Hathaway) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: ZEO/ZEO - StorageServer.py:1.32.6.9 Message-ID: <200203281830.g2SIUGD21707@cvs.baymountain.com> Update of /cvs-repository/ZEO/ZEO In directory cvs.zope.org:/tmp/cvs-serv21692 Modified Files: Tag: Standby-branch StorageServer.py Log Message: Transactional undo needs to generate invalidation messages. === ZEO/ZEO/StorageServer.py 1.32.6.8 => 1.32.6.9 === def transactionalUndo(self, trans_id, id): self._check_tid(id, exc=StorageTransactionError) - return self.__storage.transactionalUndo(trans_id, self._transaction) + oids = self.__storage.transactionalUndo(trans_id, self._transaction) + for oid in oids: + self.__invalidated.append((oid, None)) + return oids def undo(self, transaction_id): oids = self.__storage.undo(transaction_id) From jeremy at zope.com Thu Mar 28 15:30:04 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - start.py:1.29.2.2 Message-ID: <200203282030.g2SKU4j22123@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv22112 Modified Files: Tag: zeo-1_0-debug-branch start.py Log Message: Reformat some code for readability. === StandaloneZODB/ZEO/start.py 1.29.2.1 => 1.29.2.2 === signal.signal(signal.SIGTERM, - lambda sig, frame, s=storages: shutdown(s) - ) + lambda sig, frame, s=storages: shutdown(s)) signal.signal(signal.SIGINT, - lambda sig, frame, s=storages: shutdown(s, 0) - ) - try: signal.signal(signal.SIGHUP, rotate_logs_handler) - except: pass - - except: pass + lambda sig, frame, s=storages: shutdown(s, 0)) + try: + signal.signal(signal.SIGHUP, rotate_logs_handler) + except: + pass + except: + pass items=storages.items() items.sort() @@ -236,13 +236,16 @@ ZEO.StorageServer.StorageServer(unix, storages) - try: ppid, pid = os.getppid(), os.getpid() - except: pass # getpid not supported - else: open(zeo_pid,'w').write("%s %s" % (ppid, pid)) + try: + ppid, pid = os.getppid(), os.getpid() + except: + pass # getpid not supported + else: + open(zeo_pid,'w').write("%s %s" % (ppid, pid)) except: # Log startup exception and tell zdaemon not to restart us. - info=sys.exc_info() + info = sys.exc_info() try: import zLOG zLOG.LOG("z2", zLOG.PANIC, "Startup exception", @@ -280,21 +283,29 @@ # unnecessary, since we now use so_reuseaddr. for ignored in 1,2: for socket in asyncore.socket_map.values(): - try: socket.close() - except: pass + try: + socket.close() + except: + pass for storage in storages.values(): - try: storage.close() - except: pass + try: + storage.close() + except: + pass try: from zLOG import LOG, INFO LOG('ZEO Server', INFO, "Shutting down (%s)" % (die and "shutdown" or "restart") ) - except: pass + except: + pass - if die: sys.exit(0) - else: sys.exit(1) + if die: + sys.exit(0) + else: + sys.exit(1) -if __name__=='__main__': main(sys.argv) +if __name__ == '__main__': + main(sys.argv) From jeremy at zope.com Thu Mar 28 18:50:48 2002 From: jeremy at zope.com (Jeremy Hylton) Date: Sun Aug 10 16:31:20 2008 Subject: [ZEO-Checkins] CVS: StandaloneZODB/ZEO - StorageServer.py:1.34.2.7 Message-ID: <200203282350.g2SNomS28686@cvs.baymountain.com> Update of /cvs-repository/StandaloneZODB/ZEO In directory cvs.zope.org:/tmp/cvs-serv28675 Modified Files: Tag: zeo-1_0-debug-branch StorageServer.py Log Message: Fix subtle bug in new status() method. It must "return _noreturn" because the client calls it with sendMessage(). Otherwise, the server will send a return value for status() and kill the client with a "release unlocked lock" error. === StandaloneZODB/ZEO/StorageServer.py 1.34.2.6 => 1.34.2.7 === lines.append("\t" + c.stats()) log.info(string.join(lines, "\n")) + return _noreturn storage_methods={} for n in (