我认为Gevent是一个非常普遍的用例。我需要一个监听请求的UDP服务器,并根据请求将POST提交到外部Web服务。外部Web服务基本上一次只允许一个请求。
我想要一个异步UDP服务器,以便可以立即检索和存储数据,这样我就不会错过任何请求(使用DatagramServer gevent提供的这部分很容易)。然后,我需要某种方式将请求串行发送到外部Web服务,但这种方式不会破坏UDP服务器的异步。
我首先尝试用猴子修补所有内容,最终得到的是一种快速解决方案,但是在该解决方案中,我对外部Web服务的请求没有任何速率限制,从而导致错误。
似乎我需要的是一个单一的非阻塞工作程序,以串行方式将请求发送到外部Web服务,而UDP服务器将任务添加到该非阻塞工作程序正在工作的队列中。
我需要的是有关运行gevent服务器以及用于其他任务(尤其是队列)的其他greenlet的信息。我一直在使用DatagramServer的serve_forever
函数,并认为我需要改用start
方法,但尚未找到有关如何将它们组合在一起的更多信息。
谢谢,
编辑
答案非常有效。我已经使用@mguijarr的答案修改了UDP server example代码,以为我的用例生成一个可行的示例:
from __future__ import print_function
from gevent.server import DatagramServer
import gevent.queue
import gevent.monkey
import urllib
gevent.monkey.patch_all()
n = 0
def process_request(q):
while True:
request = q.get()
print(request)
print(urllib.urlopen('https://test.com').read())
class EchoServer(DatagramServer):
__q = gevent.queue.Queue()
__request_processing_greenlet = gevent.spawn(process_request, __q)
def handle(self, data, address):
print('%s: got %r' % (address[0], data))
global n
n += 1
print(n)
self.__q.put(n)
self.socket.sendto('Received %s bytes' % len(data), address)
if __name__ == '__main__':
print('Receiving datagrams on :9000')
EchoServer(':9000').serve_forever()
最佳答案
这是我的处理方式:
此函数可能是模块级函数,而不是DatagramServer实例的一部分:
def process_requests(q):
while True:
request = q.get()
# do your magic with 'request'
...
self.__q = gevent.queue.Queue()
self.__request_processing_greenlet = gevent.spawn(process_requests, self.__q)
self.__q.put(request)
这应该做您想要的。您仍然在DatagramServer上调用“serve_forever”,没问题。