我设法编写了一个相当愚蠢的bug,它会使我的一个请求处理程序运行一个非常慢的DB查询。
有趣的是,我注意到,即使在围攻完成很久之后,龙卷风仍然在翻腾请求(有时是90年代以后)。(评论-->我不是100%确定围攻的工作原理,但我相当肯定它关闭了连接..)
我通读了代码,似乎什么也找不到。尽管我的请求处理程序在上面的bug中异步运行,但挂起的请求数量堆积到了一个降低应用程序速度的水平,关闭连接会更好。
当客户端删除连接时,Tornado不会自动关闭请求处理程序。但是,您可以重写_connection_close上的,以便在客户端掉线时发出警报,这将允许您取消端上的连接。可以使用上下文管理器(或装饰器)来设置处理请求的超时;使用
Tornado.ioloop.ioloop.add_timeout
调度某个方法,该方法将请求超时到Timeout
之后运行,作为上下文管理器__enter__
的一部分,然后在上下文管理器的__exit__
块中取消该回调。这里有一个例子演示了这两种观点:
import time
import contextlib
from tornado.ioloop import IOLoop
import tornado.web
from tornado import gen
@gen.coroutine
def async_sleep(timeout):
yield gen.Task(IOLoop.instance().add_timeout, time.time() + timeout)
@contextlib.contextmanager
def auto_timeout(self, timeout=2): # Seconds
handle = IOLoop.instance().add_timeout(time.time() + timeout, self.timed_out)
try:
yield handle
except Exception as e:
print("Caught %s" % e)
finally:
IOLoop.instance().remove_timeout(handle)
if not self._timed_out:
self.finish()
else:
raise Exception("Request timed out") # Don't continue on passed this point
class TimeoutableHandler(tornado.web.RequestHandler):
def initialize(self):
self._timed_out = False
def timed_out(self):
self._timed_out = True
self.write("Request timed out!\n")
self.finish() # Connection to client closes here.
# You might want to do other clean up here.
class MainHandler(TimeoutableHandler):
@gen.coroutine
def get(self):
with auto_timeout(self): # We'll timeout after 2 seconds spent in this block.
self.sleeper = async_sleep(5)
yield self.sleeper
print("writing") # get will abort before we reach here if we timed out.
self.write("hey\n")
def on_connection_close(self):
# This isn't the greatest way to cancel a future, since it will not actually
# stop the work being done asynchronously. You'll need to cancel that some
# other way. Should be pretty straightforward with a DB connection (close
# the cursor/connection, maybe?)
self.sleeper.set_exception(Exception("cancelled"))
application = tornado.web.Application([
(r"/test", MainHandler),
])
application.listen(8888)
IOLoop.instance().start()
我见过龙卷风文档和示例,其中self.write方法被广泛用于在超文本标记语言上呈现一些值,其中POST请求在处理程序中运行。但是我找不到关于如何将响应返回给客户的清晰信息。 例如,我正在从我的客户端调用Tornado服务器上的POST请求。接受post请求的代码为: 有了这个,我可以找到cbtp的值,有了,我可以用HTML打印它。但是,相反,我想以JSON格式将这个值返回给客户机,比如我想知道如
问题内容: 我有一个传入的对象。如何找到发出请求的客户端的 IP ?我浏览了的大多数方法和属性,似乎错过了一些东西。 问题答案: (来自RequestHandler的实例) 您可以像这样检查响应:
问题内容: 我想使用python库龙卷风(版本4.2)进行一些异步HTTP请求。但是,由于出现异常:我无法强迫将来完成(使用),因为“ DummyFuture不支持阻止结果”。 我有python 3.4.3,因此将来的支持应该成为标准库的一部分。的文档说: 如果有龙卷风,将使用。否则,它将使用此模块中定义的兼容类。 下面提供了我尝试做的一个最小示例: 如果我正确理解我的问题,则会发生此问题,因为未
我已经建立一个网站一段时间了,我仍然坚持那件事: 我在dbm数据库中为我的网站存储了一些小视频(最多大约400MB),我想在我的网站上播放它们。 我正在使用Tornado python框架手工构建请求处理程序,我想知道如何构建我的处理程序。我从未发现媒体流是如何工作的,也没有在网上找到很多话题。 所以我想要实现的完整结果是在我的网站上有一个网络播放器,在那里我可以请求特定的视频,然后播放它们,而不
如何获得我的python龙卷风模块版本的当前版本? 与其他软件包,我可以做到以下几点: 来源:如何检查python模块的版本?
在Spring的反应式中,是否有一种适当的方法来设置特定于请求的超时,但仍然使用单个?