Split network_layer.py into async and sync modules

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Works as Designed
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Python Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      pymongo/network_layer.py is the only significant networking module that has not been split into pymongo/asynchronous/ and pymongo/synchronous/ counterparts, unlike most of the rest of the codebase. It currently contains both sync and async code in a single file, with both sides importing only what they need by name.

      Motivation

      Splitting the module would:

      • Make the async/sync boundary explicit and consistent with the rest of pymongo
      • Allow dedicated unit tests for each side without needing asyncio.run() workarounds in the sync test path
      • Reduce cognitive overhead when reading the file (the reader doesn't need to mentally filter sync vs async)

      Proposed Structure

      File Contents
      pymongo/network_layer_shared.py (or keep in top-level) Constants (_UNPACK_HEADER, _UNPACK_COMPRESSION_HEADER, BLOCKING_IO_ERRORS, _PYPY, _WINDOWS, _POLL_TIMEOUT), NetworkingInterfaceBase, NetworkingInterface
      pymongo/asynchronous/network_layer.py PyMongoProtocol, AsyncNetworkingInterface, async_socket_sendall, _async_socket_sendall_ssl, _async_socket_receive_ssl, async_receive_data_socket, _async_socket_receive, _poll_cancellation, async_sendall, async_receive_message
      pymongo/synchronous/network_layer.py wait_for_read, receive_data, receive_message, sendall

      Complications to be aware of

      1. Sync and async implementations are not simple async/await transforms of each other. receive_message() loops directly over receive_data(); async_receive_message() uses asyncio.wait() with a parallel cancellation task. Synchro cannot generate one from the other.
      2. Module-level platform branching. _async_socket_sendall_ssl and _async_socket_receive_ssl are defined twice under if sys.platform != "win32": ... else: ... at module level. This needs careful handling during the split.
      3. Shared symbols. NetworkingInterfaceBase, NetworkingInterface, and the constants are used by both sides and would need a shared home (similar to pool_shared.py).
      4. Import sites. pymongo/synchronous/pool.py, pymongo/asynchronous/pool.py, pymongo/synchronous/network.py, pymongo/asynchronous/network.py, pymongo/synchronous/encryption.py, pymongo/asynchronous/encryption.py, and pymongo/pool_shared.py all import from pymongo.network_layer and would need updating.

            Assignee:
            Unassigned
            Reporter:
            Alex Clark
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: