Commit df4bd2cd authored by Jens Vagelpohl's avatar Jens Vagelpohl Committed by GitHub

Merge pull request #182 from zopefoundation/python38-and-39

#165 more accurate asyncio.CancelledError handling
parents afaf0eb9 0e70fd26
......@@ -27,6 +27,14 @@ jobs:
- ["3.7", "py37-mtacceptor-msgpack1"]
- ["3.7", "py37-uvloop"]
- ["3.7", "py37-zodbmaster"]
- ["3.8", "py38"]
- ["3.8", "py38-mtacceptor"]
- ["3.8", "py38-mtacceptor-msgpack1"]
- ["3.8", "py38-uvloop"]
- ["3.9", "py39"]
- ["3.9", "py39-mtacceptor"]
- ["3.9", "py39-mtacceptor-msgpack1"]
- ["3.9", "py39-uvloop"]
- ["pypy2", "pypy"]
- ["pypy3", "pypy3"]
- ["pypy3", "pypy3-mtacceptor"]
......
Changelog
=========
5.2.4 (unreleased)
5.3.0 (unreleased)
------------------
- Add support for Python 3.8 and Python 3.9.
- Add more accurate error handling for ``asyncio.CancelledError``.
See `issue 165 <https://github.com/zopefoundation/ZEO/issues/165>`_.
- Fix bug related to blobs stored by ``ZEO``
`#150 <https://github.com/zopefoundation/ZEO/issues/150>`_.
......@@ -26,7 +31,6 @@ Changelog
- Improve log message when client cache is out of sync with server.
See `issue 142 <https://github.com/zopefoundation/ZEO/issues/142>`_.
5.2.2 (2020-08-11)
------------------
......
......@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
version = '5.2.4.dev0'
version = '5.3.0.dev0'
from setuptools import setup, find_packages
import os
......@@ -48,6 +48,8 @@ Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Database
......
......@@ -122,19 +122,25 @@ class Protocol(base.Protocol):
cr = self.loop.create_unix_connection(
self.protocol_factory, self.addr, ssl=self.ssl)
# an ``asyncio.Future``
self._connecting = cr = asyncio.ensure_future(cr, loop=self.loop)
@cr.add_done_callback
def done_connecting(future):
if future.exception() is not None:
logger.info("Connection to %r failed, retrying, %s",
self.addr, future.exception())
# keep trying
if not self.closed:
self.loop.call_later(
self.connect_poll + local_random.random(),
self.connect,
)
if future.cancelled():
logger.info("Connection to %r cancelled", self.addr)
elif future.exception() is not None:
logger.info("Connection to %r failed, %s",
(self.addr, future.exception()))
else: return
# keep trying
if not self.closed:
logger.info("retry connecting %r", self.addr)
self.loop.call_later(
self.connect_poll + local_random.random(),
self.connect,
)
def connection_made(self, transport):
super(Protocol, self).connection_made(transport)
......@@ -482,10 +488,10 @@ class Client(object):
self.verify_invalidation_queue = [] # See comment in init :(
protocol = self.protocol
if server_tid is None:
server_tid = yield protocol.fut('lastTransaction')
try:
if server_tid is None:
server_tid = yield protocol.fut('lastTransaction')
cache = self.cache
if cache:
cache_tid = cache.getLastTid()
......
......@@ -251,12 +251,18 @@ class ZEOServer(object):
def loop_forever(self):
if self.options.testing_exit_immediately:
print("testing exit immediately")
sys.stdout.flush() # ensure truthful output order
else:
self.server.loop()
def close_server(self):
if self.server is not None:
self.server.close()
if getattr(self.options, "testing_exit_immediately", False):
acceptor = self.server.acceptor
if hasattr(acceptor, "event_loop"):
# usually, this happens automatically - but not for testing
acceptor.event_loop.close()
def handle_sigterm(self):
log("terminated by SIGTERM")
......
......@@ -1221,7 +1221,7 @@ def client_asyncore_thread_has_name():
"""
def runzeo_without_configfile():
"""
r"""
>>> with open('runzeo', 'w') as r:
... _ = r.write('''
... import sys
......@@ -1231,10 +1231,13 @@ def runzeo_without_configfile():
... ''' % sys.path)
>>> import subprocess, re
>>> print(re.sub(br'\d\d+|[:]', b'', subprocess.Popen(
>>> proc = subprocess.Popen(
... [sys.executable, 'runzeo', '-a:0', '-ft', '--test'],
... stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
... ).stdout.read()).decode('ascii'))
... )
>>> proc.wait()
0
>>> print(re.sub(br'\d\d+|[:]', b'', proc.stdout.read()).decode('ascii'))
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
------
--T INFO ZEO.runzeo () opening storage '1' using FileStorage
......@@ -1242,9 +1245,10 @@ def runzeo_without_configfile():
--T INFO ZEO.StorageServer StorageServer created RW with storages 1RWt
------
--T INFO ZEO.asyncio... listening on ...
testing exit immediately
------
--T INFO ZEO.StorageServer closing storage '1'
testing exit immediately
>>> proc.stdout.close()
"""
def close_client_storage_w_invalidations():
......
......@@ -4,6 +4,8 @@ envlist =
py35
py36
py37
py38
py39
pypy
pypy3
simple
......
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