簡體   English   中英

Python Tornado更新請求之間的共享數據

[英]Python Tornado updating shared data between requests

我有一個Python Tornado應用程序。 該應用程序包含請求處理程序,我將數據傳遞給喜歡(下面的代碼不完整,只是為了說明我想要的):

configs = {'some_data': 1, # etc.
          }

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [('/pageone', PageOneHandler, configs),
                    ('/pagetwo', PageTwoHandler, configs)]
        settings = dict(template_path='/templates',
                    static_path='/static', debug=False)
        tornado.web.Application.__init__(self, handlers, **settings)

# Run the instance
# ... code goes here ...
application = Application()
http_server = tornado.httpserver.HTTPServer(application)
# ... other code (bind to port, etc.)

# 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()

我希望update_configs函數更新上面定義的configs變量,並讓此更改通過處理程序傳播。 例如(我知道這不起作用):

def update_configs():
    configs['some_data'] += 1

# Now, assuming PageOneHandler just prints out configs['some_data'], I'd expect
# the output to be: "1" on the first load, "2" if I load the page a second
# later, "4" if I load the page two seconds after that, etc.

問題是, configs變量在Application類的構造函數中創建期間傳遞給處理Application 如何更新定期回調函數中的configs['some_data']

我對這種機制的實際用例是每configs從數據庫中刷新存儲在configs字典中的數據。

有沒有一個簡單的方法可以做到這一點,而不是擺弄application.handlers (我在過去一小時左右嘗試過)?

除了上面提到的dano之外,另一種策略是將共享數據附加到Application對象。

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()

接下來,您可以使用self.application.shared_attribute訪問所有request handlers上面定義的shared_attribute

您在一個地方更新它,它會立即反映在您對請求處理程序的所有后續調用中。

好吧,最簡單的方法是將整個配置字典傳遞給處理程序,而不僅僅是dict中的各個值。 因為dicts是可變的,所以你對dict中的值所做的任何更改都會傳播到所有處理程序:

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()

輸出:

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}

對我來說,這種方法最有意義; configs中包含的數據實際上並不屬於RequestHandler任何一個實例,它是所有RequsetHandler共享的全局狀態,以及PeriodicCallback 因此,我認為嘗試創建該狀態的X個副本是不合理的,然后嘗試手動保持所有這些不同的副本同步。 相反,只需使用帶有類變量的自定義對象或dict,在整個過程中共享狀態,如上所示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM