Commit a9330b7e authored by Jim Fulton's avatar Jim Fulton Committed by GitHub

Merge pull request #44 from zopefoundation/simplify-server-commit-lock-management

Simplify server commit lock management
parents 815f39d1 3d02129b
This diff is collapsed.
...@@ -35,7 +35,7 @@ To use this module, replace:: ...@@ -35,7 +35,7 @@ To use this module, replace::
from .asyncio.server import Acceptor from .asyncio.server import Acceptor
with: with::
from .asyncio.mtacceptor import Acceptor from .asyncio.mtacceptor import Acceptor
......
...@@ -165,11 +165,13 @@ class Delay(object): ...@@ -165,11 +165,13 @@ class Delay(object):
def reply(self, obj): def reply(self, obj):
self.sent = 'reply' self.sent = 'reply'
if self.protocol:
self.protocol.send_reply(self.msgid, obj) self.protocol.send_reply(self.msgid, obj)
def error(self, exc_info): def error(self, exc_info):
self.sent = 'error' self.sent = 'error'
logger.error("Error raised in delayed method", exc_info=exc_info) logger.error("Error raised in delayed method", exc_info=exc_info)
if self.protocol:
self.protocol.send_error(self.msgid, exc_info[1]) self.protocol.send_error(self.msgid, exc_info[1])
def __repr__(self): def __repr__(self):
......
...@@ -30,6 +30,8 @@ from ZEO._compat import StringIO ...@@ -30,6 +30,8 @@ from ZEO._compat import StringIO
logger = logging.getLogger('ZEO.tests.forker') logger = logging.getLogger('ZEO.tests.forker')
DEBUG = os.environ.get('ZEO_TEST_SERVER_DEBUG')
class ZEOConfig: class ZEOConfig:
"""Class to generate ZEO configuration file. """ """Class to generate ZEO configuration file. """
...@@ -88,7 +90,7 @@ def runner(config, qin, qout, timeout=None, ...@@ -88,7 +90,7 @@ def runner(config, qin, qout, timeout=None,
debug=False, name=None, debug=False, name=None,
keep=False, protocol=None): keep=False, protocol=None):
if debug: if debug or DEBUG:
debug_logging() debug_logging()
old_protocol = None old_protocol = None
......
...@@ -48,6 +48,7 @@ class FakeServer: ...@@ -48,6 +48,7 @@ class FakeServer:
'1': FakeStorage(), '1': FakeStorage(),
'2': FakeStorageBase(), '2': FakeStorageBase(),
} }
lock_managers = storages
def register_connection(*args): def register_connection(*args):
return None, None return None, None
...@@ -58,6 +59,8 @@ class FakeConnection: ...@@ -58,6 +59,8 @@ class FakeConnection:
protocol_version = b'Z4' protocol_version = b'Z4'
addr = 'test' addr = 'test'
call_soon_threadsafe = lambda f, *a: f(*a)
def test_server_record_iternext(): def test_server_record_iternext():
""" """
......
...@@ -169,6 +169,7 @@ So, we arrange to get an error in vote: ...@@ -169,6 +169,7 @@ So, we arrange to get an error in vote:
>>> zs = ZEO.tests.servertesting.client(server, 1) >>> zs = ZEO.tests.servertesting.client(server, 1)
>>> zs.tpc_begin('0', '', '', {}) >>> zs.tpc_begin('0', '', '', {})
>>> zs.storea(ZODB.utils.p64(99), ZODB.utils.z64, 'x', '0') >>> zs.storea(ZODB.utils.p64(99), ZODB.utils.z64, 'x', '0')
>>> zs.vote('0') >>> zs.vote('0')
Traceback (most recent call last): Traceback (most recent call last):
... ...
...@@ -176,7 +177,7 @@ So, we arrange to get an error in vote: ...@@ -176,7 +177,7 @@ So, we arrange to get an error in vote:
When we do, the storage server's transaction lock shouldn't be held: When we do, the storage server's transaction lock shouldn't be held:
>>> '1' in server._commit_locks >>> zs.lock_manager.locked is not None
False False
Of course, if vote suceeds, the lock will be held: Of course, if vote suceeds, the lock will be held:
...@@ -186,7 +187,7 @@ Of course, if vote suceeds, the lock will be held: ...@@ -186,7 +187,7 @@ Of course, if vote suceeds, the lock will be held:
>>> zs.storea(ZODB.utils.p64(99), ZODB.utils.z64, 'x', '1') >>> zs.storea(ZODB.utils.p64(99), ZODB.utils.z64, 'x', '1')
>>> _ = zs.vote('1') # doctest: +ELLIPSIS >>> _ = zs.vote('1') # doctest: +ELLIPSIS
>>> '1' in server._commit_locks >>> zs.lock_manager.locked is not None
True True
>>> zs.tpc_abort('1') >>> zs.tpc_abort('1')
...@@ -361,13 +362,13 @@ release the lock and one of the waiting clients will get the lock. ...@@ -361,13 +362,13 @@ release the lock and one of the waiting clients will get the lock.
>>> zs2.notify_disconnected() # doctest: +ELLIPSIS >>> zs2.notify_disconnected() # doctest: +ELLIPSIS
ZEO.StorageServer INFO ZEO.StorageServer INFO
(test-addr-2) disconnected during locked transaction (test-addr-...) disconnected during locked transaction
ZEO.StorageServer CRITICAL ZEO.StorageServer CRITICAL
(test-addr-2) ('1') unlock: transactions waiting: 10 (test-addr-...) ('1') unlock: transactions waiting: 10
ZEO.StorageServer WARNING ZEO.StorageServer WARNING
(test-addr-1) ('1') lock: transactions waiting: 9 (test-addr-...) ('1') lock: transactions waiting: 9
ZEO.StorageServer BLATHER ZEO.StorageServer BLATHER
(test-addr-1) Preparing to commit transaction: 1 objects, ... bytes (test-addr-...) Preparing to commit transaction: 1 objects, ... bytes
(In practice, waiting clients won't necessarily get the lock in order.) (In practice, waiting clients won't necessarily get the lock in order.)
...@@ -392,45 +393,19 @@ statistics using the server_status method: ...@@ -392,45 +393,19 @@ statistics using the server_status method:
If clients disconnect while waiting, they will be dequeued: If clients disconnect while waiting, they will be dequeued:
>>> for client in clients: >>> for client in clients:
... client.notify_disconnected() ... client.notify_disconnected() # doctest: +ELLIPSIS
ZEO.StorageServer INFO ZEO.StorageServer INFO
(test-addr-10) disconnected during unlocked transaction (test-addr-10) disconnected during unlocked transaction
ZEO.StorageServer WARNING ZEO.StorageServer WARNING
(test-addr-10) ('1') dequeue lock: transactions waiting: 8 (test-addr-10) ('1') dequeue lock: transactions waiting: 8
ZEO.StorageServer INFO ...
(test-addr-11) disconnected during unlocked transaction
ZEO.StorageServer WARNING >>> zs1.server_status()['waiting']
(test-addr-11) ('1') dequeue lock: transactions waiting: 7 0
ZEO.StorageServer INFO
(test-addr-12) disconnected during unlocked transaction
ZEO.StorageServer WARNING
(test-addr-12) ('1') dequeue lock: transactions waiting: 6
ZEO.StorageServer INFO
(test-addr-13) disconnected during unlocked transaction
ZEO.StorageServer WARNING
(test-addr-13) ('1') dequeue lock: transactions waiting: 5
ZEO.StorageServer INFO
(test-addr-14) disconnected during unlocked transaction
ZEO.StorageServer WARNING
(test-addr-14) ('1') dequeue lock: transactions waiting: 4
ZEO.StorageServer INFO
(test-addr-15) disconnected during unlocked transaction
ZEO.StorageServer DEBUG
(test-addr-15) ('1') dequeue lock: transactions waiting: 3
ZEO.StorageServer INFO
(test-addr-16) disconnected during unlocked transaction
ZEO.StorageServer DEBUG
(test-addr-16) ('1') dequeue lock: transactions waiting: 2
ZEO.StorageServer INFO
(test-addr-17) disconnected during unlocked transaction
ZEO.StorageServer DEBUG
(test-addr-17) ('1') dequeue lock: transactions waiting: 1
ZEO.StorageServer INFO
(test-addr-18) disconnected during unlocked transaction
ZEO.StorageServer DEBUG
(test-addr-18) ('1') dequeue lock: transactions waiting: 0
>>> zs1.tpc_abort(tid1) >>> zs1.tpc_abort(tid1)
ZEO.StorageServer DEBUG
(test-addr-1) ('1') unlock: transactions waiting: 0
>>> logging.getLogger('ZEO').setLevel(logging.NOTSET) >>> logging.getLogger('ZEO').setLevel(logging.NOTSET)
>>> logging.getLogger('ZEO').removeHandler(handler) >>> logging.getLogger('ZEO').removeHandler(handler)
...@@ -494,6 +469,8 @@ ZEOStorage as closed and see if trying to get a lock cleans it up: ...@@ -494,6 +469,8 @@ ZEOStorage as closed and see if trying to get a lock cleans it up:
>>> zs1.connection.connection_lost(None) >>> zs1.connection.connection_lost(None)
ZEO.StorageServer INFO ZEO.StorageServer INFO
(test-addr-1) disconnected during locked transaction (test-addr-1) disconnected during locked transaction
ZEO.StorageServer DEBUG
(test-addr-1) ('1') unlock: transactions waiting: 0
>>> zs2 = ZEO.tests.servertesting.client(server, '2') >>> zs2 = ZEO.tests.servertesting.client(server, '2')
ZEO.asyncio.base INFO ZEO.asyncio.base INFO
...@@ -508,6 +485,8 @@ ZEOStorage as closed and see if trying to get a lock cleans it up: ...@@ -508,6 +485,8 @@ ZEOStorage as closed and see if trying to get a lock cleans it up:
(test-addr-2) Preparing to commit transaction: 1 objects, ... bytes (test-addr-2) Preparing to commit transaction: 1 objects, ... bytes
>>> zs2.tpc_abort(tid2) >>> zs2.tpc_abort(tid2)
ZEO.StorageServer DEBUG
(test-addr-2) ('1') unlock: transactions waiting: 0
>>> logging.getLogger('ZEO').setLevel(logging.NOTSET) >>> logging.getLogger('ZEO').setLevel(logging.NOTSET)
>>> logging.getLogger('ZEO').removeHandler(handler) >>> logging.getLogger('ZEO').removeHandler(handler)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment