Skip to content

Commit

Permalink
Documentation: Removed reuse_port option from UDP clients (#375)
Browse files Browse the repository at this point in the history
  • Loading branch information
francis-clairicia authored Nov 9, 2024
1 parent e3b678b commit 90a4e9c
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 54 deletions.
7 changes: 2 additions & 5 deletions src/easynetwork/clients/async_udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,11 @@ def __init__(
Connection Parameters:
address: A pair of ``(host, port)`` for connection.
local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally.
reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing
endpoints are bound to, so long as they all set this flag when being created.
This option is not supported on Windows and some Unixes.
If the SO_REUSEPORT constant is not defined then this capability is unsupported.
family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``.
Socket Parameters:
socket: An already connected UDP :class:`socket.socket`. If `socket` is given,
none of and `local_address` and `reuse_port` should be specified.
none of `family` and `local_address` should be specified.
"""
super().__init__()

Expand Down
12 changes: 2 additions & 10 deletions src/easynetwork/clients/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ def __init__(
*,
local_address: tuple[str, int] | None = ...,
family: int = ...,
reuse_port: bool = ...,
retry_interval: float = ...,
) -> None: ...

Expand Down Expand Up @@ -86,14 +85,11 @@ def __init__(
Connection Parameters:
address: A pair of ``(host, port)`` for connection.
local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally.
reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing
endpoints are bound to, so long as they all set this flag when being created.
This option is not supported on Windows and some Unixes.
If the SO_REUSEPORT constant is not defined then this capability is unsupported.
family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``.
Socket Parameters:
socket: An already connected UDP :class:`socket.socket`. If `socket` is given,
none of and `local_address` and `reuse_port` should be specified.
none of `family` and `local_address` should be specified.
Keyword Arguments:
retry_interval: The maximum wait time to wait for a blocking operation before retrying.
Expand Down Expand Up @@ -309,7 +305,6 @@ def _create_udp_socket(
*,
local_address: tuple[str, int] | None = None,
family: int = _socket.AF_UNSPEC,
reuse_port: bool = False,
) -> _socket.socket:

errors: list[OSError] = []
Expand All @@ -324,9 +319,6 @@ def _create_udp_socket(
errors.clear()
raise
try:
if reuse_port:
_utils.set_reuseport(socket)

if local_address is not None:
socket.bind(local_address)

Expand Down
2 changes: 1 addition & 1 deletion src/easynetwork/lowlevel/api_async/backend/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ async def create_udp_endpoint(
remote_host: The host IP/domain name.
remote_port: Port of connection.
local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally.
family: The address family
family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``.
Raises:
OSError: unrelated OS error occurred.
Expand Down
7 changes: 4 additions & 3 deletions src/easynetwork/servers/async_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,10 @@ def __init__(
ssl_standard_compatible: if :data:`False`, skip the closing handshake when closing the connection,
and don't raise an exception if the peer does the same.
backlog: is the maximum number of queued connections passed to :class:`~socket.socket.listen` (defaults to ``100``).
reuse_port: tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints
are bound to, so long as they all set this flag when being created.
This option is not supported on Windows.
reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing
endpoints are bound to, so long as they all set this flag when being created.
This option is not supported on Windows and some Unixes.
If the SO_REUSEPORT constant is not defined then this capability is unsupported.
max_recv_size: Read buffer size. If not given, a default reasonable value is used.
log_client_connection: If :data:`True`, log clients connection/disconnection in :data:`logging.INFO` level.
(This log will always be available in :data:`logging.DEBUG` level.)
Expand Down
7 changes: 4 additions & 3 deletions src/easynetwork/servers/async_udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ def __init__(
backend: The :term:`asynchronous backend interface` to use.
Keyword Arguments:
reuse_port: tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints
are bound to, so long as they all set this flag when being created.
This option is not supported on Windows.
reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing
endpoints are bound to, so long as they all set this flag when being created.
This option is not supported on Windows and some Unixes.
If the SO_REUSEPORT constant is not defined then this capability is unsupported.
logger: If given, the logger instance to use.
"""
super().__init__(
Expand Down
33 changes: 1 addition & 32 deletions tests/unit_test/test_sync/test_client/test_udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,9 @@ def test____dunder_init____create_datagram_endpoint____default(
@pytest.mark.parametrize(
"local_address", [None, ("local_address", 12345)], ids=lambda p: f"local_address=={p}", indirect=True
)
@pytest.mark.parametrize("reuse_port", [False, True], ids=lambda p: f"reuse_port=={p}")
def test____dunder_init____create_datagram_endpoint____with_parameters(
self,
request: pytest.FixtureRequest,
reuse_port: bool,
socket_family: int,
local_address: tuple[str, int] | None,
remote_address: tuple[str, int],
Expand All @@ -207,7 +205,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters(
mock_datagram_protocol,
family=socket_family,
local_address=local_address,
reuse_port=reuse_port,
)
request.addfinalizer(client.close)

Expand All @@ -216,7 +213,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters(
family=socket_family,
local_address=local_address,
remote_address=remote_address,
reuse_port=reuse_port,
)
assert mock_udp_socket.mock_calls == [
mocker.call.getpeername(),
Expand All @@ -227,11 +223,9 @@ def test____dunder_init____create_datagram_endpoint____with_parameters(
@pytest.mark.parametrize(
"local_address", [None, ("local_address", 12345)], ids=lambda p: f"local_address=={p}", indirect=True
)
@pytest.mark.parametrize("reuse_port", [False, True], ids=lambda p: f"reuse_port=={p}")
def test____dunder_init____create_datagram_endpoint____with_parameters____explicit_AF_UNSPEC(
self,
request: pytest.FixtureRequest,
reuse_port: bool,
local_address: tuple[str, int] | None,
remote_address: tuple[str, int],
mock_datagram_protocol: MagicMock,
Expand All @@ -245,7 +239,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters____explic
mock_datagram_protocol,
family=AF_UNSPEC,
local_address=local_address,
reuse_port=reuse_port,
)
request.addfinalizer(client.close)

Expand All @@ -254,7 +247,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters____explic
family=AF_UNSPEC,
local_address=local_address,
remote_address=remote_address,
reuse_port=reuse_port,
)

@pytest.mark.parametrize("socket_family", list(UNSUPPORTED_FAMILIES), indirect=True)
Expand Down Expand Up @@ -917,7 +909,6 @@ def test____create_udp_socket____default(
mock_socket_ipv4.close.assert_not_called()

@pytest.mark.parametrize("with_local_address", [False, True], ids=lambda boolean: f"with_local_address=={boolean}")
@pytest.mark.parametrize("set_reuse_port", [False, True], ids=lambda boolean: f"set_reuse_port=={boolean}")
@pytest.mark.parametrize(
["family", "socket_families"],
[
Expand All @@ -930,14 +921,12 @@ def test____create_udp_socket____default(
def test____create_udp_socket____with_parameters(
self,
with_local_address: bool,
set_reuse_port: bool,
family: int,
socket_families: tuple[int, ...],
mock_socket_cls: MagicMock,
mock_getaddrinfo: MagicMock,
mock_socket_ipv4: MagicMock,
mock_socket_ipv6: MagicMock,
SO_REUSEPORT: int,
) -> None:
# Arrange
remote_address: tuple[str, int] = ("remote_address", 12345)
Expand All @@ -948,7 +937,6 @@ def test____create_udp_socket____with_parameters(
local_address=local_address,
remote_address=remote_address,
family=family,
reuse_port=set_reuse_port,
)

# Assert
Expand All @@ -967,10 +955,7 @@ def test____create_udp_socket____with_parameters(
mock_socket_cls.assert_called_once_with(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
used_socket = mock_socket_ipv6
not_used_socket = mock_socket_ipv4
if set_reuse_port:
used_socket.setsockopt.assert_called_once_with(SOL_SOCKET, SO_REUSEPORT, True)
else:
used_socket.setsockopt.assert_not_called()
used_socket.setsockopt.assert_not_called()
if local_address is None:
used_socket.bind.assert_not_called()
else:
Expand Down Expand Up @@ -1104,22 +1089,6 @@ def test____create_udp_socket____all_failed(
mock_socket_ipv6.connect.assert_not_called()
mock_socket_ipv6.close.assert_not_called()

@pytest.mark.usefixtures("remove_SO_REUSEPORT_support")
def test____create_udp_socket____SO_REUSEPORT_not_supported(
self,
mock_socket_ipv4: MagicMock,
) -> None:
# Arrange
remote_address: tuple[str, int] = ("remote_address", 12345)
local_address: tuple[str, int] = ("local_address", 11111)

# Act
with pytest.raises(ValueError):
_ = create_udp_socket(local_address=local_address, remote_address=remote_address, reuse_port=True)

# Assert
mock_socket_ipv4.close.assert_called_once_with()

@pytest.mark.parametrize("fail_on", ["socket", "bind"], ids=lambda fail_on: f"fail_on=={fail_on}")
def test____create_udp_socket____unrelated_exception(
self,
Expand Down

0 comments on commit 90a4e9c

Please sign in to comment.