Skip to main content

roboflex.transport.zmq

Roboflex support for the ZMQ transport.

any node -> ZMQPublisher ==THEINTERNET==> ZMQSubscriber -> any node

See https://zeromq.org/ for details.

Using ZMQ, nodes can connect to other nodes, running in different threads, different processes, or different computers, with a publisher-subscriber pattern. roboflex.transport.zmq supports:

"inproc" transport -> between threads within same process
"ipc" transport -> between processes on same computer
"tcp" transport -> between processes on different computers

System Dependencies

None! We build libzmq from source...

pip install

pip install roboflex.transport.zmq

Import (python)

import roboflex.transport.zmq as rtz

Build (for c++ projects):

mkdir build && cd build
cmake ..
make
make install

Python bindings are off by default for plain C++ CMake builds. To build them with CMake directly:

cmake -S . -B build -DBUILD_ROBOFLEX_TRANSPORT_ZMQ_PYTHON_EXT=ON

Run Tests

Tests are plain C++ executables registered with CTest; no separate testing library is required.

cmake -S . -B build
cmake --build build --target test_zmq_transport
ctest --test-dir build --output-on-failure

Run Examples (see examples)

go to roboflex_transport_zmq/examples

... create and activate some sort of virtual environment
where you installed roboflex.transport.zmq...

python pub_sub_0_py.py

Nodes:

There are five: ZMQContext, ZMQPublisher, ZMQSubscriber, ZMQRequestClient, and ZMQRequestServer.

To use the ZMQ transport nodes, first you must create a ZMQContext object. This mirrors the design of ZMQ itself.

# all parameters optional
zmq_context = ZMQContext(
    num_io_threads = 1,
)

First, know this. "bind addresses" in this world can be three different things. All are strings, but can create different types of queues. These all implement one-to-many publish-subscribe pattern (in fact, it's actually many-to-many).

1. thread-to-thread only queues; "inproc://somename"; the fastest.
2. process-to-process (or thread-to-thread) queues; "ipc://somename"; sort of fast.
3. computer-to-computer (can work anywhere) queues (uses TCP): "tcp://*:5647"; the slowest, but works across the planet.

Then, create a ZMQPublisher:

zmq_pub = ZMQPublisher(
    # the ZMQContext object you created
    zmq_context, 

    # what socket to bind to, or what transport to publish on
    bind_address = <bind address>,
    #    or
    bind_addresses = [<bind address>],

    # optional
    
    # name of the
    name = "ZMQPublisher",

    # same as 'high-water mark' in zeromq parlance
    max_queued_msgs = 1000,
)

#... when a ZMQPublisher receives a message from some upstream node, #it will wire-serialize it, and publish on its transport.

#You can get the bind_addresses:

ba = zmq_pub.bind_addresses

# you can get the high-water mark
hm = zmq_pub.max_queued_msgs

# You can publish a message 'by hand' - same as calling 'receive' on the node.
zmq_pub.publish(some_message)

Then, create one or more ZMQSubscribers, to listen to what you are publishing. ZMQSubscribes are the equivalent of 'sensors' in that the are root nodes, must be started, and start a thread.

zmq_sub = ZMQSubscriber(
    # the ZMQContext object you created
    zmq_context, 

    # what socket to bind to, or what transport to subscribe on
    connect_address = <bind address>,
    #    or
    connect_addresses = [<bind address>],

    # optional
    
    # name of the
    name = "ZMQPublisher",

    # same as 'high-water mark' in zeromq parlance
    max_queued_msgs = 1000,

    # how often to yield control on the thread
    # You'll probably never change this.
    timeout_milliseconds = 10,
)

# you get get values
zmq_sub.connect_addresses
zmq_sub.connect_address
zmq_sub.max_queued_msgs
zmq_sub.timeout_milliseconds

# you MUST start it!
zmq_sub.start()

# you may pull a message 'by hand':
msg_or_none = zmq_sub.pull(
    10, # timeout_milliseconds - how long to wait for a message
)

# you may 'produce' messages 'by hand' - this will wait x milliseconds
# for one message, and if it has received one, signals it downstream
zmq_sub.produce(
    10, # timeout_milliseconds
)

RPC / Request-Reply

For request-response workloads, use ZMQRequestClient and ZMQRequestServer instead of PUB/SUB. This avoids subscriber lazy-join behavior and gives the caller a normal blocking call.

These classes use ZMQ REQ/REP. A client has one outstanding request at a time; concurrent calls are serialized.

def handler(msg):
    # inspect the request and return a roboflex Message
    return msg

ctx = ZMQContext()

server = ZMQRequestServer(
    ctx,
    "tcp://*:5555",
    request_handler = handler,
)
server.start()

client = ZMQRequestClient(
    ctx,
    "tcp://127.0.0.1:5555",
    timeout_milliseconds = 1000,
)

reply = client.call({"hello": "world"}, timeout_milliseconds = 1000)

ZMQRequestClient is also a node: when it receives a message, it performs a blocking call and signals the response downstream.

Metadata

Release files for roboflex.transport.zmq 0.1.17

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for roboflex.transport.zmq 0.1.17
File Size Uploaded
roboflex_transport_zmq-0.1.17.tar.gz 17.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for roboflex.transport.zmq 0.1.17
File Interpreter ABI Platform
roboflex_transport_zmq-0.1.17-cp311-cp311-macosx_15_0_arm64.whl CPython 3.11 CPython 3.11 macOS 15.0+ ARM64 Details

Total release size: 1.1 MB

Release files / roboflex_transport_zmq-0.1.17.tar.gz

Download URL roboflex_transport_zmq-0.1.17.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6fc44e8139125eac92348c637e5b31328c8789394462cb59ac740e9859d79b5a
BLAKE2b-256 checksum
How to use checksums
d0ff18b6c3c70369edf1050eb41211f8689f030b26a524339a51857722b7de17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / roboflex_transport_zmq-0.1.17-cp311-cp311-macosx_15_0_arm64.whl

Download URL roboflex_transport_zmq-0.1.17-cp311-cp311-macosx_15_0_arm64.whl
Size 1.0 MB
Tags CPython 3.11 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
a93e747f71e01868a613319b2cc1d353ed128050e2a124730d29f1df739b087f
BLAKE2b-256 checksum
How to use checksums
ee86fe1e42889cc5b7b687291223b794e68f003031eb79826246a40c25cfeb81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release history Release notifications | RSS feed

This release

0.1.17 This release

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

1 release file

0.1.12

1 release file

0.1.11

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page