6

サブプロセスを使用してリクエストのほとんどの作業を行うBottleアプリケーションがあります。単一の応答を返すルートの場合、次のようなことを行います。

@route('/index')
def index():
    worker = getWorker()
    return worker.doStuff()

私のルートの1つはデータストリームである必要があります。ワーカーに応答ストリームを返させるスマートな方法がわかりません。以下の例は、私がやりたいことと似ていますが、ワーカーがいないだけです。

@route('/stream')
def stream():
    yield 'START'
    sleep(3)
    yield 'MIDDLE'
    sleep(5)
    yield 'END'

以下のようなことができるようになりたいです。ジェネレーターを譲り渡す/返すことができないので、これはこの方法では不可能です。

@route('/stream')
def stream():
    worker = getWorker()
    yield worker.doStuff()
class worker:
    # Remember, this is run in a subprocess in real life.
    def doStuff():
        yield 'START'
        sleep(3)
        yield 'MIDDLE'
        sleep(5)
        yield 'END'

これは大規模なプロジェクト用であり、私は物事を行う方法にあまり柔軟性がありません。最も簡単な答えは「あなたのデザインが間違っている」ということです。ただし、この場合、制御できない制約がいくつかあります(ルートはデータストリームである必要があり、作業はサブプロセスによって実行される必要があります)。

編集 私もdoStuff()ブロックを持つことはできません。戻ってワーカープロセスを実行するgeventキューのようなものを作成できるようにしたいと思います。現在の問題は、gevent.queueとProcessを一緒に使用できないように見えることです。

@route('/stream')
def index():
    body = gevent.queue.Queue()
    worker = multiprocessing.Process(target=do_stuff, args=body)
    worker.start()
    return body()

def do_stuff(body):
    while True:
        gevent.sleep(5)
        body.put("data")
4

2 に答える 2

2

多くの調査と実験の結果、このようにPythonマルチプロセッシングでgeventキューを使用することはできないと判断しました。このようにする代わりに、redisのようなものを使用して、プロセスとgeventグリーンレットが通信できるようにすることができます。

@route('/stream')
def index():
    worker = multiprocessing.Process(target=do_stuff)
    worker.start()
    yield redis_server.lpop()

def do_stuff(body):
    while True:
        gevent.sleep(5)
        redis_server.lpush("data")
于 2013-01-17T18:40:19.940 に答える
1

最後の例でworker.doStuff()は、反復可能なジェネレーターを返します。あなたはそれを返すことができます(に変更yieldしてくださいreturn)。ボトルは、バイトまたはユニコード文字列を生成する限り、反復可能値を戻り値として受け入れます。

于 2012-11-10T14:45:19.543 に答える