0

as the title mentioned

example code:

import gevent
from gevent.queue import Queue

class Worker(gevent.Greenlet):
    def __init__(self, sock):
        self.queue = Queue()
        self.sock = sock
        super(Worker, self).__init__()

    def _run(self):
        self.running = True
        while self.running:
            msg_from_queue = self.queue.get()    # block call
            msg_from_sock = self.sock.recv(128)  # block call

worker = Worker(sock)
worker.start()

I wanna worker handle two events:

  1. message recv from sock
  2. message get from queue

but the two are all block calls

How should I do, to let worker get from sock and queue at the same time?

Yueyoum
  • 2,823
  • 5
  • 23
  • 26

2 Answers2

1

I found a way:

class Worker(gevent.Greenlet):
    def _sock_recv(self):
        # ...
    def _queue_get(self):
        # ...
    def _run(self):
        recv = gevent.spawn(self._sock_recv)
        get = gevent.spawn(self._queue_get)
        gevent.joinall([recv, get])
Yueyoum
  • 2,823
  • 5
  • 23
  • 26
0

How about Splitting Worker into two workers?

class QueueWorker(gevent.Greenlet):
    def __init__(self, queue):
        self.queue = queue
        super(QueueWorker, self).__init__()

    def _run(self):
        self.running = True
        while self.running:
            msg = self.queue.get()    # block call
            print 'queue:', msg


class SocketWorker(gevent.Greenlet):
    def __init__(self, sock):
        self.sock = sock
        super(SocketWorker, self).__init__()

    def _run(self):
        self.running = True
        while self.running:
            msg = self.sock.recv(128)  # block call
            print 'socket:', msg

worker1 = QueueWorker(queue)
worker1.start()
worker2 = SocketWorker(sock)
worker2.start()
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Hi, Look below, I found a way for this. But still thanks for helping – Yueyoum Jun 17 '13 at 08:46
  • @Yueyoum, `gevent.joinall()` waits for all jobs to complete. Is that what you want? – falsetru Jun 17 '13 at 08:55
  • I'm not sure. gevent.joinall() only waits this worker's sub jobs, not the whole program process, right? In a test , I create three/four workers, It's working fine now. – Yueyoum Jun 17 '13 at 09:36
  • `gevnet.joinall([recv, get])` wait for `recv`, `get` **both** to complete, not the whole program process. – falsetru Jun 17 '13 at 09:38
  • yes, this what I wanted, `joinall([recv, get])` to let the two greenlet run, and `recv` complete before `get`. So, there additional codes in my project: `def clear(*args): get.kill(); recv.link(clear)`.So , when `rece` completed , then kill `get` greenlate, finally, this worker exit automatically – Yueyoum Jun 17 '13 at 09:42
  • I misunderstood. Maybe while loops are inside _sock_recv, _queue_get? – falsetru Jun 17 '13 at 09:42