0

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 を使用しても役に立ちません。

イベント ループ コールバックでブロックしている可能性のあるソースからデータをフェッチする方法はありますか?

4

1 に答える 1

0

を取り除くとtimeout=10、ブロッキング ソースからのデータを待ちます。(参照: http://www.gevent.org/gevent.queue.html、デフォルトの動作。)

read_callback() のブロックがfor i in xrange(10)ループの操作に干渉する場合は、たとえばgevent.spawn().

また、デフォルトでput()は、キューがいっぱいになるとブロックされることに注意してください。put_nowait()put(timeout=...)、またはput(block=False)デフォルトの動作を変更することを検討してください。

于 2012-10-03T16:27:18.743 に答える