Python 从不同的tornado.RequestHandler实例访问/更新全局/共享defaultdict

Python 从不同的tornado.RequestHandler实例访问/更新全局/共享defaultdict,python,python-3.x,tornado,defaultdict,Python,Python 3.x,Tornado,Defaultdict,从不同的RequestHandler实例访问/更新全局defaultdict安全吗?例如 GlobalMap = defaultdict(list) class Event(tornado.web.RequestHandler): def get(self, unit): # This is where the access/modify might happen # The list.append() is just an arbitrary exam

从不同的
RequestHandler
实例访问/更新全局
defaultdict
安全吗?例如

GlobalMap = defaultdict(list)

class Event(tornado.web.RequestHandler):
    def get(self, unit):
        # This is where the access/modify might happen
        # The list.append() is just an arbitrary example
        GlobalMap[unit].append(datetime.utcnow()) 
        self.write(b'') 

如果没有,在不同的
RequestHandler
实例之间查找/存储键控数据的正确方法是什么?

是的,可以这样做。Tornado代码通常在主线程中运行;任何访问像这样的Python数据结构的代码


但是,如果您要在生产环境中部署Tornado应用程序,您需要多个Tornado进程,可能在多台计算机上运行,因此您需要将数据放入共享数据库服务器中,以便在进程之间共享。

在异步/线程/多进程应用程序中,访问全局变量的安全性与创建全局变量的安全性相同。正如中所述,共享状态从来都不是一个好主意。但在大多数情况下,从全局
dict
访问值是相当安全的,尤其是在单线程异步应用程序中

另一方面,将所有
RequestHandler
类放在一个模块中最终会变得难以控制。使用字典作为数据存储将无法有效扩展。A.Jesse Jiryu Davis在他的回答中暗示的是,您在
GlobalMap
中拥有的数据应该存储在某种数据库中,以便共享。有过多的数据库解决方案“感觉”很像传统的
dict
对象,如和Redis

更新 在构建
应用程序
对象时,还可以传入其他参数。因此,在主模块中,您可以执行以下操作:

GlobalMap = defaultdict(list)

class Event(tornado.web.RequestHandler):
    def initialize(self, shared_dict):
        self.shared_dict = shared_dict

app = Application([
    #...
    (r"/", Event, dict(shared_dict=GlobalMap))
])

请看一下和。我觉得有点傻,没有早点回忆起这件事。这将处理Tornado应用程序之间的可访问性,但其他模块的可访问性不强,在这种情况下,您肯定需要一个外部数据库。

我认为“Tornado可以扩展到数万个开放连接”。是否需要运行多个tornado服务器实例才能实现这一点。如果我多次启动tornado.py,我不需要绑定到多个不同的套接字地址吗?然后,如何将传入流量路由到多个不同的内部套接字?所有这些都超出了原始问题的范围,但是你的第二段。龙卷风可以处理数千个连接。可以使用多个实例来分配工作。然后,使用gunicron、nginx或其他负载平衡器在实例之间对流量进行负载平衡。这是典型的企业级应用程序,但如果您将Tornado用于个人用途,我不会过多地强调多个实例。此应用程序实际上是特意设计的小型/简单/单个文件。如果我将其设置为大于一个文件,则表明我做错了什么。:)但是,撇开这一点不谈,为了处理跨模块的边界问题,可以将“全局”数据作为tornado.application实例的一个属性吗?然后让请求只访问
self.application.\u myGlobalMap['foo']
?我不明白为什么不能在
tornado.application
中添加类变量,但我认为更简单的方法是在应用程序创建过程中传递它。请参阅我的最新答案。正如你所看到的,我对龙卷风也相当陌生;P