33

redis の pubsub を使用していくつかのメッセージを送信したいのですがlisten、以下のコードのようにを使用してブロックされたくありません。

import redis
rc = redis.Redis()

ps = rc.pubsub()
ps.subscribe(['foo', 'bar'])

rc.publish('foo', 'hello world')

for item in ps.listen():
    if item['type'] == 'message':
        print item['channel']
        print item['data']

最後のforセクションはブロックします。特定のチャネルにデータがあるかどうかを確認したいのですが、どうすればこれを達成できますか? check同様の方法はありますか?

4

11 に答える 11

50

非ブロッキングの非同期処理を考えている場合は、おそらく非同期フレームワーク/サーバーを使用している (または使用する必要がある) でしょう。

更新: 元の回答から 5 年が経ちましたが、その間に Python はネイティブの非同期 IO サポートを取得しました。非同期 IO Redis クライアント である AIORedisが追加されました。

于 2013-01-08T16:32:43.510 に答える
17

redis-py の新しいバージョンは、非同期 pubsub をサポートしています。詳細については、 https://github.com/andymccurdy/redis-pyを確認してください。ドキュメント自体の例を次に示します。

while True:
    message = p.get_message()
    if message:
        # do something with the message
    time.sleep(0.001)  # be nice to the system :)
于 2014-06-26T12:38:13.947 に答える
8

これは、ブロッキング リスナーをスレッド化する実際の例です。

import sys
import cmd
import redis
import threading


def monitor():
    r = redis.Redis(YOURHOST, YOURPORT, YOURPASSWORD, db=0)

    channel = sys.argv[1]
    p = r.pubsub()
    p.subscribe(channel)

    print 'monitoring channel', channel
    for m in p.listen():
        print m['data']


class my_cmd(cmd.Cmd):
    """Simple command processor example."""

    def do_start(self, line):
        my_thread.start()

    def do_EOF(self, line):
        return True


if __name__ == '__main__':
    if len(sys.argv) == 1:
        print "missing argument! please provide the channel name."
    else:
        my_thread = threading.Thread(target=monitor)
        my_thread.setDaemon(True)

        my_cmd().cmdloop()
于 2012-01-10T07:55:24.490 に答える
8

そんなことはありえないと思います。チャネルには「現在のデータ」がありません。チャネルにサブスクライブし、チャネル上の他のクライアントによってプッシュされているメッセージの受信を開始するため、ブロック API です。また、pub/sub の Redis Commands ドキュメントを見ると、より明確になります。

于 2011-10-24T05:21:11.640 に答える
1

The most efficient approach would be greenlet-based rather than thread-based. As a greenlet-based concurrency framework, gevent is already quite established in the Python world. A gevent integration with redis-py would be therefore be wonderful. That is exactly what's being discussed in this issue on github:

https://github.com/andymccurdy/redis-py/issues/310

于 2013-01-24T16:15:36.953 に答える
1

ノンブロッキング コードに到達するには、別の種類のパラダイム コードを実行する必要があります。新しいスレッドを使用してすべての変更をリッスンし、メインスレッドを離れて別のことを行うのは難しくありません。

また、メイン スレッドと redis サブスクライバー スレッドの間でデータを交換するための何らかのメカニズムが必要になります。

于 2011-10-24T18:05:25.743 に答える
0

gevent、geventモンキーパッチを使用して、非ブロッキングのredispubsubアプリを構築できます。

于 2012-11-28T12:44:10.437 に答える