title: Gevent async server with blocking requests
body: <p>I have what I would think is a pretty common use case for Gevent. I need a UDP server that listens for requests, and based on the request submits a POST to an external web service. The external web service essentially only allows one request at a time.</p>
  
  <p>I would like to have an asynchronous UDP server so that data can be immediately retrieved and stored so that I don't miss any requests (this part is easy with the DatagramServer gevent provides). Then I need some way to send requests to the external web service serially, but in such a way that it doesn't ruin the async of the UDP server.</p>
  
  <p>I first tried monkey patching everything and what I ended up with was a quick solution, but one in which my requests to the external web service were not rate limited in any way and which resulted in errors.</p>
  
  <p>It seems like what I need is a single non-blocking worker to send requests to the external web service in serial while the UDP server adds tasks to the queue from which the non-blocking worker is working.</p>
  
  <p>What I need is information on running a gevent server with additional greenlets for other tasks (especially with a queue). I've been using the <code>serve_forever</code> function of the DatagramServer and think that I'll need to use the <code>start</code> method instead, but haven't found much information on how it would fit together.</p>
  
  <p>Thanks,</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>The answer worked very well. I've adapted the <a href="https://github.com/surfly/gevent/blob/master/examples/udp_server.py" rel="nofollow">UDP server example</a> code with the answer from @mguijarr to produce a working example for my use case:</p>
  
  <pre><code>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()
  </code></pre>