响应在龙卷风中产生了结果
Response yielded result in Tornado
我想通过 websockets 创建 Messenger。我的逻辑是:User_1
通过 tornado 处理程序向 User_2
发送一条消息 (json),在 tornado 服务器上检查一条消息 (def send_message_to_RDB_parallel
)(对 RDB 的一些请求, PostgreSQL),然后 User_1
收到响应,User_2
收到消息。
检查对 RDB 的请求 (def send_message_to_RDB_parallel
) - 可能会阻止我的龙卷风服务器。因此,我想通过 Celery(使用 RabbitMQ)来完成它,或者只是放弃它。据我了解,它可以帮助我解锁龙卷风服务器。但是我需要在完成时得到回复。我可以使用或不使用 Celery 启动它,但我无法得到响应。当我破坏我的龙卷风服务器(按 Ctrl-C)时,我看到一个错误,如“...对象不可调用”
如何获得响应并发送 (self.write_message()
)?
在这个例子中,我尝试只使用 yield
class MessagesHandler(tornado.websocket.WebSocketHandler):
...
def on_message(self, mess):
...
self.send_message_to_RDB(thread_id=thread_id,
sender_id=self.user_id,
recipient_id=recipient_id,
message=message['msg'],
time=datetime.datetime.now(datetime.timezone.utc),
check=True)
...
@tornado.gen.coroutine
def send_message_to_RDB(self, thread_id, sender_id, recipient_id, message, time, check):
response = yield tornado.gen.Task(send_message_to_RDB_parallel(thread_id=thread_id,
sender_id=sender_id,
recipient_id=recipient_id,
message=message,
time=time,
check=check))
if response.result[0] is False:
self.write_message(response.result[1])
def send_message_to_RDB_parallel(thread_id, sender_id, recipient_id, message, time, check=False):
"""
Send message to rdb. Check thread. One recipient_id !
"""
# tf__ = False
if check is True:
if recipient_id == sender_id:
return False, to_json_error(MessengerRecipientEqualSenderServerMessage[1])
if User.objects.filter(id=recipient_id,
is_deleted=False,
is_active=True,
is_blocked=False).exists() is False:
return False, to_json_error("Wrong User")
...
else:
me = Message()
me.text = message
me.thread_id = thread_id
me.sender_id = sender_id
me.datetime = time
me.save()
return True, None
有几个一般性错误:
send_message_to_RDB_parallel
不是异步的,甚至没有回调参数,但你试图将它与 gen.Task
一起使用 - 不会设置任何结果
on_message
是协程,它在 send_message_to_RDB
中被调用,但是它没有被生成(等待)
gen.Task
接受一个函数(和可选的附加参数)并运行它,但它实际上是你调用它的代码没有传递
因为 2) 不会引发任何进一步发生的错误,这样您就可以在 ^C
之后看到它们。必须阅读 http://www.tornadoweb.org/en/stable/guide/async.html
解决方案
当然你可以使用 celery 并异步等待结果 (Tornado celery integration hacks)..
但如果您使用 Postgres,我建议您使用现有的异步库 ():
- momoko - postgres Tornado-based 客户端,它不是 ORM,
- aiopg - postgres asyncio-based 客户端(Tornado 4.3 及以上版本),支持 sqlalchemy 查询构建器
我想通过 websockets 创建 Messenger。我的逻辑是:User_1
通过 tornado 处理程序向 User_2
发送一条消息 (json),在 tornado 服务器上检查一条消息 (def send_message_to_RDB_parallel
)(对 RDB 的一些请求, PostgreSQL),然后 User_1
收到响应,User_2
收到消息。
检查对 RDB 的请求 (def send_message_to_RDB_parallel
) - 可能会阻止我的龙卷风服务器。因此,我想通过 Celery(使用 RabbitMQ)来完成它,或者只是放弃它。据我了解,它可以帮助我解锁龙卷风服务器。但是我需要在完成时得到回复。我可以使用或不使用 Celery 启动它,但我无法得到响应。当我破坏我的龙卷风服务器(按 Ctrl-C)时,我看到一个错误,如“...对象不可调用”
如何获得响应并发送 (self.write_message()
)?
在这个例子中,我尝试只使用 yield
class MessagesHandler(tornado.websocket.WebSocketHandler):
...
def on_message(self, mess):
...
self.send_message_to_RDB(thread_id=thread_id,
sender_id=self.user_id,
recipient_id=recipient_id,
message=message['msg'],
time=datetime.datetime.now(datetime.timezone.utc),
check=True)
...
@tornado.gen.coroutine
def send_message_to_RDB(self, thread_id, sender_id, recipient_id, message, time, check):
response = yield tornado.gen.Task(send_message_to_RDB_parallel(thread_id=thread_id,
sender_id=sender_id,
recipient_id=recipient_id,
message=message,
time=time,
check=check))
if response.result[0] is False:
self.write_message(response.result[1])
def send_message_to_RDB_parallel(thread_id, sender_id, recipient_id, message, time, check=False):
"""
Send message to rdb. Check thread. One recipient_id !
"""
# tf__ = False
if check is True:
if recipient_id == sender_id:
return False, to_json_error(MessengerRecipientEqualSenderServerMessage[1])
if User.objects.filter(id=recipient_id,
is_deleted=False,
is_active=True,
is_blocked=False).exists() is False:
return False, to_json_error("Wrong User")
...
else:
me = Message()
me.text = message
me.thread_id = thread_id
me.sender_id = sender_id
me.datetime = time
me.save()
return True, None
有几个一般性错误:
send_message_to_RDB_parallel
不是异步的,甚至没有回调参数,但你试图将它与gen.Task
一起使用 - 不会设置任何结果on_message
是协程,它在send_message_to_RDB
中被调用,但是它没有被生成(等待)gen.Task
接受一个函数(和可选的附加参数)并运行它,但它实际上是你调用它的代码没有传递
因为 2) 不会引发任何进一步发生的错误,这样您就可以在 ^C
之后看到它们。必须阅读 http://www.tornadoweb.org/en/stable/guide/async.html
解决方案
当然你可以使用 celery 并异步等待结果 (Tornado celery integration hacks)..
但如果您使用 Postgres,我建议您使用现有的异步库 (
- momoko - postgres Tornado-based 客户端,它不是 ORM,
- aiopg - postgres asyncio-based 客户端(Tornado 4.3 及以上版本),支持 sqlalchemy 查询构建器