HTTPアップロードを実行するために、GeventでPycurlを使用しようとしています。このために、 libcurl のマルチAPI を Gevent のイベント ループを使用するように変更するgeventcurl.pyモジュールに依存しています。
問題はREADFUNCTIONコールバックにあります。このコールバックはHUBコンテキストで実行されるため、 wait()はできませんが、このコールバックはアップロードするデータを返す必要があり、私の場合、このデータはブロッキング ソースから取得されます。
問題を示すコードのスニペットを次に示します。
#!/usr/bin/env python
from gevent import monkey; monkey.patch_all()
import gevent
from gevent.queue import Queue
import pycurl
from geventcurl import Curl
URL = 'http://localhost:8000/'
class QueueReader:
def __init__(self, q):
self.q = q
def read_callback(self, size):
return self.q.get(timeout=10)
dataq = Queue(10)
c = Curl()
c.setopt(pycurl.URL, URL)
c.setopt(pycurl.UPLOAD, 1)
c.setopt(pycurl.READFUNCTION, QueueReader(dataq).read_callback)
# Start transfer
g = gevent.spawn(c.perform)
for i in xrange(10):
dataq.put(str(i))
gevent.sleep(1)
g.join()
c.close()
スニペットを実行するには、localhost:8000 で何かをリッスンする必要がありnc -l 8000
ます。HUB コンテキストで実行されるためread_callback()
、待ちません。キューが空の場合、すぐに Empy 例外が発生します。結果を待つ必要があるため、 AsyncResult を使用しても役に立ちません。
イベント ループ コールバックでブロックしている可能性のあるソースからデータをフェッチする方法はありますか?