我应该如何保护数据库在初始化之前不被访问
我有一个数据库。它需要初始化。这可能需要时间,因此初始化将返回延迟的。我们称之为延迟d_db_ready
我还有其他方法,比如说read_a_value_from_the_database()
,它们希望访问数据库,但只有在数据库初始化之后
轻松点!我将回调添加到d_db_ready
:
d_value = d_db_ready.addCallback(read_a_value_from_the_database)
现在,我希望从数据库中得到的值可以在Deferredd_value
中找到
让我们再试一次:
d_value2 = d_db_ready.addCallback(read_a_value_from_the_database)
这次不行了。这是因为d_db_ready
的回调链现在以我们从数据库读取的值结束。它不再允许访问数据库
这里应该使用什么模式?在初始化数据库之前,我应该如何保护它不被访问
一个选项是read_a_value_from_the_database
返回数据库。。。但这样就不会返回值。此外,这种方法是一个可怕的潜在错误的来源:当我忘记返回数据库时,我必须找出以前调用过的函数,而我所拥有的只是当前调用的函数
下面是一些可运行的代码来演示我的问题:
from twisted.internet.defer import Deferred
database = "uninitialized"
d_db_ready = Deferred()
def init_database():
global database
print("Initializing database")
database = { "value": 1 }
d_db_ready.callback(database)
def read_a_value_from_the_database(db):
value = db["value"]
print("value:", value)
return value
d_db_ready.addCallback(read_a_value_from_the_database)
d_db_ready.addCallback(read_a_value_from_the_database) # <--- errors
init_database()
根据@Jean-PaulCalderone回答中的第二个选项,下面是一个基于延迟的实现:
注意
d_db_ready
现在应该被认为是函数get_database()
的私有函数,用户不应该再访问它您展示的模式已经很好地防止了在数据库准备就绪之前使用数据库。它的问题是不支持多种用途。第二次回调不会失败,因为它得到了一个未初始化的数据库。它只有在数据库初始化后才会失败,因为它获取的是先前操作的结果,而不是数据库
有两种常见的选择。一是停止多种用途。这并不像听起来那么荒谬。例如:
现在
d_db_ready
上唯一的回调是run_the_program
,而run_the_program
负责将数据库传递到需要的地方第二种选择是使您的就绪API支持多种用途。这里有许多不同的实现方法,但它们都围绕着打破延迟的结果链接特性。例如,您可以这样做:
safe_callback
确保d_db_ready
的结果始终是数据库,而不是某个随机回调的结果这一想法可能有更好的实现(例如,一个仍然基于
Deferred
的实现,而不是放弃传递裸回调的功能)。希望这个简单的例子能给你一个大致的想法相关问题 更多 >
编程相关推荐