Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/protocol/test_conn_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import threading

from tests.protocol._fakes import FakeTransport
from trpc_sdk.protocol import ConnWriter
from trpc_sdk.protocol import _conn_writer
from trpc_sdk.transport import ConnWriter
from trpc_sdk.transport._server import _conn_writer


def test_still_importable_from_runtime_package():
Expand Down
4 changes: 2 additions & 2 deletions tests/protocol/test_session_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from tests.protocol._fakes import stream_frame
from tests.protocol._fakes import unary_frame
from trpc_sdk.abc import get_message
from trpc_sdk.protocol import TCPConnection
from trpc_sdk.protocol._cython import _tcp_protocol
from trpc_sdk.transport import TCPConnection
from trpc_sdk.transport._server._cython import _tcp_protocol
from trpc_sdk.transport import TcpConnectionOption


Expand Down
4 changes: 2 additions & 2 deletions tests/server/test_stream_thread_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from tests.protocol._fakes import stream_frame
from tests.protocol._fakes import unary_frame
from trpc_sdk.abc import STREAM_WRITER_CTX_KEY
from trpc_sdk.protocol import ConnWriter
from trpc_sdk.protocol import TCPConnection
from trpc_sdk.transport import ConnWriter
from trpc_sdk.transport import TCPConnection
from trpc_sdk.server._server import Server
from trpc_sdk.transport import TcpConnectionOption

Expand Down
2 changes: 1 addition & 1 deletion tests/transport/test_default_io_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from tests.protocol._fakes import ParserFactory
from tests.protocol._fakes import FakeTransport
from trpc_sdk.abc import BaseServerTransportOption
from trpc_sdk.protocol import TCPConnection
from trpc_sdk.transport import TCPConnection
from trpc_sdk.transport import ConnectionOption
from trpc_sdk.transport import DefaultIoConnection
from trpc_sdk.transport import TrpcServerTransport
Expand Down
43 changes: 0 additions & 43 deletions trpc_sdk/protocol/__init__.py

This file was deleted.

4 changes: 2 additions & 2 deletions trpc_sdk/runtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
:class:`~trpc_sdk.runtime._threadmodel._separate_thread.SeparateThread`
for merge mode with the separate thread model (trpc-cpp
``runtime/threadmodel`` and ``separate_runtime``); responses cross back
to the I/O loops through :class:`~trpc_sdk.protocol.ConnWriter`,
to the I/O loops through :class:`~trpc_sdk.transport.ConnWriter`,
re-exported here
- :mod:`~trpc_sdk.runtime._common` — SIGTERM callbacks, process metadata and the exit template every mode shares (trpc-cpp
``runtime/common``)
Expand All @@ -77,7 +77,7 @@
re-exports :func:`register_protocol_handle`.
"""

from trpc_sdk.protocol import ConnWriter
from trpc_sdk.transport import ConnWriter
from trpc_sdk.transport import register_protocol_handle

from ._common import ProcessInfo
Expand Down
2 changes: 1 addition & 1 deletion trpc_sdk/runtime/_threadmodel/_loop_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
``transport.write()`` from another thread is not safe. That is why every
serving loop opens its own connections to the task processes, and why the
separate thread model hands responses back through
:class:`~trpc_sdk.protocol.ConnWriter`.
:class:`~trpc_sdk.transport.ConnWriter`.

A loop thread that dies while the worker is serving is not left behind
silently: its ``on_exit`` callback tells the worker, which shuts the process
Expand Down
2 changes: 1 addition & 1 deletion trpc_sdk/runtime/_threadmodel/_separate_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
thread through
:class:`~trpc_sdk.runtime._threadmodel._handler_pool.SharedHandlerPool`, and
the handle thread hands the response back through the connection's
:class:`~trpc_sdk.protocol.ConnWriter`. Requests of one connection
:class:`~trpc_sdk.transport.ConnWriter`. Requests of one connection
may therefore run on several handle threads and complete out of order, which
tRPC already allows: responses are matched by request id.

Expand Down
46 changes: 13 additions & 33 deletions trpc_sdk/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
accepts the client TCP, splits frames, and writes them to an rpc task
pipe; :class:`RpcTaskConnection` on the rpc task runs the handler and
writes the response back
- merge mode: :class:`DefaultDatagramConnection` and the re-exported
:class:`TCPConnection` listen on the merge worker. The TCP Protocol is
owned by :mod:`trpc_sdk.protocol`; this package only forwards the name
so :class:`~trpc_sdk.runtime.MergeWorker` can import both listen
protocols from here.
- merge mode: :class:`DefaultDatagramConnection` and
:class:`TCPConnection` listen on the merge worker. Both live in
:mod:`trpc_sdk.transport._server`, so a merge worker imports them from
here.

The package is split by responsibility:

Expand All @@ -44,9 +43,11 @@
``UserProtocolTransport`` with the ``register_protocol_handle`` registry,
the plugin factory (``DefaultServerTransport*``,
:func:`get_server_transport`), and the accepted connections:
``TcpConnectionOption`` for the Cython ``TCPConnection``,
``DefaultIoConnection`` with its ``ConnectionOption`` for subclasses
calling ``set_io_connection``, ``DefaultDatagramConnection`` for UDP listen
``TcpConnectionOption`` and the Cython ``TCPConnection``
(:mod:`~trpc_sdk.transport._server._cython`), ``ConnWriter`` for
cross-thread writes, ``DefaultIoConnection`` with its ``ConnectionOption``
for subclasses calling ``set_io_connection``,
``DefaultDatagramConnection`` for UDP listen
sockets (built from the same ``ConnectionOption``), and
``ServerConnection``, the peer view both hand to ``_msg_handler``
- :mod:`~trpc_sdk.transport._separate` — the asyncio protocols on both ends
Expand All @@ -68,8 +69,6 @@

from __future__ import annotations

from importlib import import_module

from trpc_sdk.abc import BaseServerTransportOption

from ._cython import InnerStreamParser # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -103,6 +102,7 @@
from ._client import get_client_transport
from ._client import get_default_client_transport
from ._client import open_datagram_endpoint
from ._server import ConnWriter
from ._server import ConnectionCloseHandler
from ._server import ConnectionIdleCleanHandler
from ._server import ConnectionInitHandler
Expand All @@ -115,6 +115,7 @@
from ._server import MsgHandler
from ._server import ProtocolStarter
from ._server import ServerConnection
from ._server import TCPConnection
from ._server import TcpConnectionOption
from ._server import TrpcServerStreamTransport
from ._server import TrpcServerTransport
Expand Down Expand Up @@ -152,6 +153,8 @@
"TrpcServerStreamTransport",
"UserProtocolTransport",
"IpcStreamWriter",
"ConnWriter",
"TCPConnection",
"TcpConnectionOption",
"DefaultIoConnection",
"ConnectionOption",
Expand All @@ -177,8 +180,6 @@
"SeparateRpczConnection",
# Separate-mode rpc task protocol
"RpcTaskConnection",
# Executor / merge-worker listen protocols
"TCPConnection",
# Shared types and hooks
"ClientConnectionInfo",
"SchedulerParams",
Expand All @@ -192,24 +193,3 @@
"InnerStreamParser",
"encode_worker_msg_req",
]


_LAZY_EXPORTS = {
"TCPConnection": ("trpc_sdk.protocol", "TCPConnection"),
}


def __getattr__(name: str):
"""Lazily export symbols that would otherwise load too early.

:class:`TCPConnection` is owned by :mod:`trpc_sdk.protocol` and is only
needed once a merge worker is already serving. Resolving it on first
access is enough.
"""
spec = _LAZY_EXPORTS.get(name)
if spec is None:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
module_name, attr_name = spec
value = getattr(import_module(module_name, package=__name__), attr_name)
globals()[name] = value
return value
9 changes: 9 additions & 0 deletions trpc_sdk/transport/_server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
``set_io_connection``, with its :class:`ConnectionOption` and the
``MsgHandler`` / ``Connection*Handler`` callback types it holds; and
:class:`ServerConnection`, the peer view ``_msg_handler`` reads
- :mod:`~trpc_sdk.transport._server._cython` — :class:`TCPConnection`, the
Cython asyncio Protocol for one accepted client TCP socket, and
:func:`handle_request`
- :mod:`~trpc_sdk.transport._server._conn_writer` — :class:`ConnWriter`, the
handle that writes on a connection's transport from any thread
- :mod:`~trpc_sdk.transport._server._datagram_connection` —
:class:`DefaultDatagramConnection`, the datagram protocol of a
tRPC-over-UDP listen socket, which builds one peer view per datagram
Expand All @@ -53,6 +58,8 @@
from ._acceptor import Acceptor
from ._acceptor import StreamListener
from ._acceptor import serve_stream
from ._conn_writer import ConnWriter
from ._cython import TCPConnection # pylint: disable=no-name-in-module
from ._datagram_connection import DefaultDatagramConnection
from ._stream_connection import BaseConnection
from ._stream_connection import ConnectionCloseHandler
Expand Down Expand Up @@ -81,6 +88,7 @@
"AcceptTarget",
"Acceptor",
"BaseConnection",
"ConnWriter",
"ConnectionCloseHandler",
"ConnectionIdleCleanHandler",
"ConnectionInitHandler",
Expand All @@ -92,6 +100,7 @@
"MsgHandler",
"ServerConnection",
"StreamListener",
"TCPConnection",
"TcpConnectionOption",
"TrpcServerTransport",
"TrpcServerStreamTransport",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
keep writing (DATA, CLOSE, RESET) after the client left, and the writer's
``closed`` flag is what drops those writes.

It lives in the protocol package because the TCP protocol builds it itself;
the protocol package does not import the server package.
It lives beside the TCP protocol because that protocol builds the writer
itself. The Cython module imports it with a relative import and does not
import :mod:`trpc_sdk.transport`: that package's ``__init__`` loads this
module.

Every cross-thread write costs one ``call_soon_threadsafe``; wake-ups are not
coalesced in this version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ from trpc_sdk.abc import TrpcContext
from trpc_sdk.abc import get_message
from trpc_sdk.exceptions import ServerDecodeError
from trpc_sdk.log import logger
from trpc_sdk.protocol._conn_writer import ConnWriter
from .._conn_writer import ConnWriter
from trpc_sdk.rpcz import RPCZ_SERVER_REQ_SIZE_CTX_KEY
from trpc_sdk.rpcz import RPCZ_SERVER_RSP_SIZE_CTX_KEY
from trpc_sdk.rpcz import submit_server_span_on_executor_post_io
Expand Down Expand Up @@ -178,8 +178,9 @@ cdef class TCPConnection:
"""Copy the listener's options into this connection's C-level slots.

``option`` is read by attribute name only, so this module does not
import :mod:`trpc_sdk.transport`. It is not kept: the hot path reads
the copied slots.
import :mod:`trpc_sdk.transport`. That package's ``__init__`` loads
this module; a back-import would run while it is still loading.
The option is not kept: the hot path reads the copied slots.

Args:
option: A :class:`~trpc_sdk.transport.ConnectionOption`.
Expand Down
2 changes: 1 addition & 1 deletion trpc_sdk/transport/_server/_datagram_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

from trpc_sdk.exceptions import ServerDecodeError
from trpc_sdk.log import logger
from trpc_sdk.protocol import ConnWriter
from trpc_sdk.telemetry import report_attr

from ._conn_writer import ConnWriter
from ._stream_connection import ConnectionOption
from ._stream_connection import _to_host_port

Expand Down
2 changes: 1 addition & 1 deletion trpc_sdk/transport/_server/_stream_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
business:

- merge mode (every thread model): the connection's
:class:`~trpc_sdk.protocol.ConnWriter`, which writes the raw frame on the
:class:`~trpc_sdk.transport.ConnWriter`, which writes the raw frame on the
client TCP from whichever thread the stream runs on, and drops writes once
the connection is closed;
- ``server.mode: separate``: an :class:`IpcStreamWriter` on the rpc task's
Expand Down
2 changes: 1 addition & 1 deletion trpc_sdk/transport/_server/_trpc_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
from trpc_sdk.abc import TrpcContext
from trpc_sdk.abc import get_message
from trpc_sdk.log import logger
from trpc_sdk.protocol import TCPConnection
from trpc_sdk.rpcz import RPCZ_SERVER_REQ_SIZE_CTX_KEY
from trpc_sdk.rpcz import RPCZ_SERVER_RSP_SIZE_CTX_KEY
from trpc_sdk.rpcz import submit_server_span_on_executor_post_io
Expand All @@ -63,6 +62,7 @@
from ._acceptor import StreamListener
from ._acceptor import serve_stream
from ._constants import SERVER_CONN_KEY
from ._cython import TCPConnection # pylint: disable=no-name-in-module
from ._datagram_connection import DefaultDatagramConnection
from ._stream_connection import ConnectionOption
from ._stream_connection import DefaultIoConnection
Expand Down
Loading