pyzmq icon indicating copy to clipboard operation
pyzmq copied to clipboard

BUG: SERVER socket is not compatible with asyncio

Open steamraven opened this issue 3 weeks ago • 2 comments

This is a pyzmq bug

  • [x] This is a pyzmq-specific bug, not an issue of zmq socket behavior. Don't worry if you're not sure! We'll figure it out together.

What pyzmq version?

26.2.0 (pip --no-binary)

What libzmq version?

4.3.5 (bundled, built with DRAFT_API)

Python version (and how it was installed)

python 3.12.7 from Apt

OS

Ubuntu 24.10

What happened?

Immediate exception when creating a SERVER socket using an asyncio context

pyzmq installed via Draft Install Doc

Code to reproduce bug

import zmq
from zmq.asyncio import Context
context = Context()
socket = context.socket(zmq.SERVER)

Traceback, if applicable

Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.11/site-packages/zmq/sugar/attrsettr.py", line 56, in __getattr__
    return self._get_attr_opt(upper_key, opt)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/zmq/sugar/attrsettr.py", line 68, in _get_attr_opt
    return self.get(opt)
           ^^^^^^^^^^^^^
  File "_zmq.py", line 853, in zmq.backend.cython._zmq.Socket.get
  File "_zmq.py", line 1362, in zmq.backend.cython._zmq._getsockopt
  File "_zmq.py", line 179, in zmq.backend.cython._zmq._check_rc
zmq.error.ZMQError: Invalid argument

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/workspaces/mythic/mythic_server/test_zmq_cliserv.py", line 4, in <module>
    socket = context.socket(zmq.SERVER)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/zmq/sugar/context.py", line 354, in socket
    socket_class(  # set PYTHONTRACEMALLOC=2 to get the calling frame
  File "/home/vscode/.local/lib/python3.11/site-packages/zmq/_future.py", line 231, in __init__
    self._fd = self._shadow_sock.FD
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/lib/python3.11/site-packages/zmq/sugar/attrsettr.py", line 62, in __getattr__
    raise AttributeError(f"{key} attribute is write-only")
AttributeError: FD attribute is write-only

More info

This appears to be a problem with the underlying SERVER socket being thread-safe, and the _future._AsyncSocket requesting a FD on the shadow socket.

PYzmq requests the FD from the shadow socket here in pyzmq/zmq/_future.py self._fd = self._shadow_sock.FD https://github.com/zeromq/pyzmq/blob/01bd01c77277f16f714807a3ae4769f5b726710a/zmq/_future.py#L237

The SERVER socket is created thread-safe here in libzmq/src/server.cpp socket_base_t (parent_, tid_, sid_, true), https://github.com/zeromq/libzmq/blob/34f7fa22022bed9e0e390ed3580a1c83ac4a2834/src/server.cpp#L13

The zmq_getsockattr for FD returns error if threadsafe here in libzmq/src/socket_base.cpp

    if (option_ == ZMQ_FD) {
        if (_thread_safe) {
            // thread safe socket doesn't provide file descriptor
            errno = EINVAL;
            return -1;
        }

https://github.com/zeromq/libzmq/blob/34f7fa22022bed9e0e390ed3580a1c83ac4a2834/src/socket_base.cpp#L447C1-L452C10

Unfortunately, my skill in socket and async programming are not good enough to come up with any solutions.

steamraven avatar Jan 29 '25 00:01 steamraven