1

I wrote two types of greenlets. MyGreenletPUB will publish message via ZMQ with message type 1 and message type 2. MyGreenletSUB instances will subscribe to ZMQ PUB, based on parameter ( "1" and "2" ).

Problem here is that when I start my Greenlets run method in MyGreenletSUB code will stop on message = sock.recv() and will never return run time execution to other greenlets.

My question is how can I avoid this and how can I start my greenlets asynchronous with a while TRUE, without using gevent.sleep() in while methods to switch execution between greenlets

from gevent.monkey import patch_all
patch_all()
import zmq
import time
import gevent
from gevent import Greenlet


class MyGreenletPUB(Greenlet):

    def _run(self):
        # ZeroMQ Context
        context = zmq.Context()

        # Define the socket using the "Context"
        sock = context.socket(zmq.PUB)
        sock.bind("tcp://127.0.0.1:5680")

        id = 0
        while True:
            gevent.sleep(1)
            id, now = id + 1, time.ctime()
            # Message [prefix][message]
            message = "1#".format(id=id, time=now)
            sock.send(message)

            # Message [prefix][message]
            message = "2#".format(id=id, time=now)
            sock.send(message)
            id += 1


class MyGreenletSUB(Greenlet):

    def __init__(self, b):
        Greenlet.__init__(self)
        self.b = b

    def _run(self):
        context = zmq.Context()

        # Define the socket using the "Context"
        sock = context.socket(zmq.SUB)

        # Define subscription and messages with prefix to accept.
        sock.setsockopt(zmq.SUBSCRIBE, self.b)
        sock.connect("tcp://127.0.0.1:5680")

        while True:
            message = sock.recv()
            print message


g = MyGreenletPUB.spawn()
g2 = MyGreenletSUB.spawn("1")
g3 = MyGreenletSUB.spawn("2")
try:
    gevent.joinall([g, g2, g3])
except KeyboardInterrupt:
    print "Exiting"
user3666197
  • 1
  • 6
  • 50
  • 92
user821738
  • 61
  • 1
  • 1
  • 4

1 Answers1

0

A default ZeroMQ .recv() method modus operandi is to block until there has arrived anything, that will pass to the hands of the .recv() method caller.

For indeed smart, non-blocking agents, always use rather .poll() instance-methods and .recv( zmq.NOBLOCK ).

Beware, that ZeroMQ subscription is based on topic-filter matching from left and may get issues if mixed unicode and non-unicode strings are being distributed / collected at the same time.

Also, mixing several event-loops might become a bit tricky, depends on your control-needs. I personally always prefer non-blocking systems, even at a cost of more complex design efforts.

user3666197
  • 1
  • 6
  • 50
  • 92