Python Tornado updating shared data between requests

后端 未结 2 1106
半阙折子戏
半阙折子戏 2021-02-09 03:23

I have a Python Tornado app. The app contains request handlers, for which I am passing data to like (the code below is not complete, and is just to illustrate what I want):

相关标签:
2条回答
  • 2021-02-09 03:49

    Another strategy, in addition to what dano mentions above is to attach the shared data to the Application object.

    class MyApplication(tornado.web.Application):
    
        def __init__(self):
    
           self.shared_attribute = foo;
    
            handlers = [#your handlers here]        
            settings = dict(#your application settings here)
            super().__init__(handlers, **settings)
    
    
    server = tornado.httpserver.HTTPServer(MyApplication())
    server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
    

    Next you can access shared_attribute defined above in all your request handlers using self.application.shared_attribute.

    You update it at one place and it immediately reflects in all your subsequent calls to the request handlers.

    0 讨论(0)
  • 2021-02-09 04:13

    Well, the simplest thing would be to pass the entire config dict to the handlers, rather than just the individual values inside the dict. Because dicts are mutable, any change you make to the values in the dict would then propagate to all the handlers:

    import tornado.web
    import tornado.httpserver
    
    configs = {'some_data': 1, # etc.
              }
    
    def update_configs():
        print("updating")
        configs['some_data'] += 1
    
    class PageOneHandler(tornado.web.RequestHandler):
        def initialize(self, configs):
            self.configs = configs
        def get(self):
            self.write(str(self.configs) + "\n")
    
    
    class PageTwoHandler(tornado.web.RequestHandler):
        def initialize(self, configs):
            self.configs = configs
    
        def get(self):
            self.write(str(self.configs) + "\n")
    
    
    class Application(tornado.web.Application):
        def __init__(self):
            handlers = [('/pageone', PageOneHandler, {'configs' : configs}),
                    ('/pagetwo', PageTwoHandler, {'configs': configs})]
            settings = dict(template_path='/templates',
                        static_path='/static', debug=False)
            tornado.web.Application.__init__(self, handlers, **settings)
    
    # Run the instance
    application = Application()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    
    # Callback function to update configs
    some_time_period = 1000 # Once an second
    tornado.ioloop.PeriodicCallback(update_configs, some_time_period).start()
    tornado.ioloop.IOLoop.instance().start()
    

    Output:

    dan@dantop:~> curl localhost:8888/pageone
    {'some_data': 2}
    dan@dantop:~> curl localhost:8888/pageone
    {'some_data': 3}
    dan@dantop:~> curl localhost:8888/pagetwo
    {'some_data': 4}
    dan@dantop:~> curl localhost:8888/pageone
    {'some_data': 4}
    

    To me this approach makes the most sense; the data contained in configs doesn't really belong to any one instance of a RequestHandler, it's global state shared by all RequsetHandlers, as well as your PeriodicCallback. So I don't think it makes sense to try to create X numbers of copies of that state, and then try to keep all those different copies in sync manually. Instead, just share the state across your whole process using either a custom object with class variables, or a dict, as shown above.

    0 讨论(0)
提交回复
热议问题