使用Tornado websockets和RethinkDB非阻塞地获取数据

时间:2015-12-26 19:21:31

标签: python tornado rethinkdb rethinkdb-python

当我从客户端收到消息时,我想并行运行多个RethinkDB查询并立即将结果发送给客户端。

阻挡方式如下。计数可能需要几分钟。我希望其他查询返回更快,不会被计数查询阻止。

self.write_message({'count': r.db('public').table(message['table']).count().run(conn)})
self.write_message({'rows': r.db('public').table(message['table']).limit(10).run(conn)})

我怀疑我需要https://rethinkdb.com/blog/async-drivers/http://www.tornadoweb.org/en/stable/guide/async.html

的组合

我想的可能答案是让这两行像:

ioloop.IOLoop.current().add_callback(run_query, r.db('public').table(message['table']).count(), 'count', self)
ioloop.IOLoop.current().add_callback(run_query, r.db('public').table(message['table']).limit(10), 'rows', self)

我的运行查询将是:

@gen.coroutine
def run_query(query, key, ws):
    conn = yield r.connect(host="localhost", port=28015)
    results = yield query.run(conn)
    ws.write_message({key: results})

1 个答案:

答案 0 :(得分:1)

tornado.gen doc显示解决方案:

  

您还可以提供期货的清单或字典,该清单将从中开始   同时并行运行;结果列表或词典将是   完成后返回。

# do not forget about this
r.set_loop_type("tornado")

@gen.coroutine
def run_parallel(query, key, ws):
    conn = yield r.connect(host="localhost", port=28015)
    ret = yield {
        'count': r.db('public').table(message['table']).count().run(conn),
        'rows': r.db('public').table(message['table']).limit(10).run(conn)
    }
    ws.write_message(ret)

直接产生名单或字典具有重要行为 - 如果任何期货失败,yield将立即返回并将重新提出例外,无论其他期货是否已完成。要绕过它,您可以使用Mulitmulti_future

注意:我真的不知道RethinkDB是否需要单独的连接,但我想展示概念。