Skip to content

[Doc] ROUTER-to-DEALER in C different from Python #4784

@Joshuaalbert

Description

@Joshuaalbert
  1. The bind protocols are different ipc in python vs tcp in C.
  2. Python uses a singleton zmq.Context.instance() by C creates a new context.
  3. There is not ready handshake in Python
  4. The stopping is different.

A more accurate translation is:

# ROUTER-to-DEALER LRU Queue example in Python
import time
import random
from threading import Thread

import zmq

NBR_WORKERS = 10

def worker_task(worker_id):
    # Each worker has its own context
    context = zmq.Context()
    worker = context.socket(zmq.DEALER)
    identity = f"{worker_id}".encode('ascii')
    worker.setsockopt(zmq.IDENTITY, identity)
    worker.connect("tcp://localhost:5671")

    total = 0
    while True:
        # Tell broker we're ready (two‐frame empty + greeting)
        worker.send_multipart([b'', b'Hi Boss'])

        # Wait for broker reply (empty delimiter + workload)
        empty, workload = worker.recv_multipart()
        if workload == b'Fired!':
            print(f"Worker {worker_id} completed: {total} tasks")
            break

        total += 1
        # Do some random “work” (1–500 ms)
        time.sleep(random.randint(1, 500) / 1000.0)

    worker.close()
    context.term()


def broker_task():
    context = zmq.Context()
    broker = context.socket(zmq.ROUTER)
    broker.bind("tcp://*:5671")

    # Run for 5 seconds, then fire each worker in turn
    end_time = time.time() + 5
    workers_fired = 0

    while workers_fired < NBR_WORKERS:
        # Receive next ready worker: [ identity | empty | greeting ]
        identity, empty, greeting = broker.recv_multipart()

        # Decide whether to send work or fire
        if time.time() < end_time:
            broker.send_multipart([identity, b'', b'Work harder'])
        else:
            broker.send_multipart([identity, b'', b'Fired!'])
            workers_fired += 1

    broker.close()
    context.term()


if __name__ == "__main__":
    random.seed(time.time())

    # Launch workers (each in its own context/thread)
    for i in range(NBR_WORKERS):
        Thread(target=worker_task, args=(i,), daemon=True).start()

    # Start the broker loop (blocks until all workers are fired)
    broker_task()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions