Skip to content

Commit

Permalink
Increase default ready_timeout to 5.0 (#263)
Browse files Browse the repository at this point in the history
* Increase default ready_timeout to 5.0
* Mention ready_timeout in TimeoutError message
* Bump Version to 1.4.2a1 & Update NEWS.rst
  • Loading branch information
pepoluan committed Mar 7, 2021
1 parent 9c2a13e commit f386bf9
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
2 changes: 1 addition & 1 deletion aiosmtpd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2014-2021 The aiosmtpd Developers
# SPDX-License-Identifier: Apache-2.0

__version__ = "1.4.1"
__version__ = "1.4.2a1"
22 changes: 16 additions & 6 deletions aiosmtpd/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

AsyncServer = asyncio.base_events.Server

DEFAULT_READY_TIMEOUT: float = 5.0


@public
class IP6_IS:
Expand Down Expand Up @@ -106,7 +108,7 @@ def __init__(
handler,
loop=None,
*,
ready_timeout: float = 1.0,
ready_timeout: float,
ssl_context: Optional[ssl.SSLContext] = None,
# SMTP parameters
server_hostname: Optional[str] = None,
Expand Down Expand Up @@ -207,7 +209,11 @@ def start(self):
# See comment about WSL1.0 in the _run() method
raise self._thread_exception
else:
raise TimeoutError("SMTP server failed to start within allotted time")
raise TimeoutError(
"SMTP server failed to start within allotted time. "
"This might happen if the system is too busy. "
"Try increasing the `ready_timeout` parameter."
)
respond_timeout = self.ready_timeout - (time.monotonic() - start)

# Apparently create_server invokes factory() "lazily", so exceptions in
Expand All @@ -222,7 +228,11 @@ def start(self):
# Raise other exceptions though
raise
if not self._factory_invoked.wait(respond_timeout):
raise TimeoutError("SMTP server not responding within allotted time")
raise TimeoutError(
"SMTP server started, but not responding within allotted time. "
"This might happen if the system is too busy. "
"Try increasing the `ready_timeout` parameter."
)
if self._thread_exception is not None:
raise self._thread_exception

Expand Down Expand Up @@ -265,7 +275,7 @@ def __init__(
port: int = 8025,
loop=None,
*,
ready_timeout: float = 1.0,
ready_timeout: float = DEFAULT_READY_TIMEOUT,
ssl_context: ssl.SSLContext = None,
# SMTP parameters
server_hostname: Optional[str] = None,
Expand Down Expand Up @@ -317,8 +327,8 @@ def __init__(
unix_socket: Optional[Union[str, Path]],
loop=None,
*,
ready_timeout=1.0,
ssl_context=None,
ready_timeout: float = DEFAULT_READY_TIMEOUT,
ssl_context: ssl.SSLContext = None,
# SMTP parameters
server_hostname: str = None,
**SMTP_parameters,
Expand Down
16 changes: 16 additions & 0 deletions aiosmtpd/docs/NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
###################


1.4.2 (aiosmtpd-next)
=====================

Fixed/Improved
--------------
* Controller's ``ready_timeout`` parameter increased from ``1.0`` to ``5.0``.
This won't slow down Controller startup because it's just a timeout limit
(instead of a sleep delay),
but this should help prevent Controller from giving up too soon,
especially during situations where system/network is a bit busy causing slowdowns.
(See #262)
* Timeout messages in ``Controller.start()`` gets more details and a mention about the
``ready_timeout`` parameter. (See #262)



1.4.1 (2021-03-04)
==================

Expand Down
13 changes: 9 additions & 4 deletions aiosmtpd/docs/controller.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ Controller API
handler, \
loop=None, \
*, \
ready_timeout=1.0, \
ready_timeout, \
ssl_context=None, \
server_hostname=None, server_kwargs=None, **SMTP_parameters)
Expand All @@ -292,6 +292,7 @@ Controller API
If not given, :func:`asyncio.new_event_loop` will be called to create the event loop.
:param ready_timeout: How long to wait until server starts.
The :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` takes precedence over this parameter.
See :attr:`ready_timeout` for more information.
:type ready_timeout: float
:param ssl_context: SSL Context to wrap the socket in.
Will be passed-through to :meth:`~asyncio.loop.create_server` method
Expand Down Expand Up @@ -330,14 +331,18 @@ Controller API

.. attribute:: ready_timeout
:type: float
:noindex:

The timeout value used to wait for the server to start.

This will either be the value of
the :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` environment variable (converted to float),
or the :attr:`ready_timeout` parameter.

Setting this to a high value will NOT slow down controller startup,
because it's a timeout limit rather than a sleep delay.
However, you may want to reduce the default value to something 'just enough'
so you don't have to wait too long for an exception, if problem arises.

If this timeout is breached, a :class:`TimeoutError` exception will be raised.

.. attribute:: server
Expand Down Expand Up @@ -430,7 +435,7 @@ Controller API
hostname=None, port=8025, \
loop=None, \
*, \
ready_timeout=1.0, \
ready_timeout=3.0, \
ssl_context=None, \
server_hostname=None, server_kwargs=None, **SMTP_parameters)
Expand Down Expand Up @@ -488,7 +493,7 @@ Controller API
unix_socket, \
loop=None, \
*, \
ready_timeout=1.0, \
ready_timeout=3.0, \
ssl_context=None, \
server_hostname=None,\
**SMTP_parameters)
Expand Down
2 changes: 1 addition & 1 deletion aiosmtpd/tests/test_proxyprotocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from aiosmtpd.tests.conftest import Global, controller_data, handler_data

DEFAULT_AUTOCANCEL = 0.1
TIMEOUT_MULTIPLIER = 1.5
TIMEOUT_MULTIPLIER = 2.0

param = pytest.param
parametrize = pytest.mark.parametrize
Expand Down
12 changes: 10 additions & 2 deletions aiosmtpd/tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ class TestController:
@pytest.mark.filterwarnings("ignore")
def test_ready_timeout(self):
cont = SlowStartController(Sink())
expectre = r"SMTP server failed to start within allotted time"
expectre = (
"SMTP server failed to start within allotted time. "
"This might happen if the system is too busy. "
"Try increasing the `ready_timeout` parameter."
)
try:
with pytest.raises(TimeoutError, match=expectre):
cont.start()
Expand All @@ -133,7 +137,11 @@ def test_ready_timeout(self):
@pytest.mark.filterwarnings("ignore")
def test_factory_timeout(self):
cont = SlowFactoryController(Sink())
expectre = r"SMTP server not responding within allotted time"
expectre = (
r"SMTP server started, but not responding within allotted time. "
r"This might happen if the system is too busy. "
r"Try increasing the `ready_timeout` parameter."
)
try:
with pytest.raises(TimeoutError, match=expectre):
cont.start()
Expand Down

0 comments on commit f386bf9

Please sign in to comment.