视图依赖于Redis来填充。 Redis由每10分钟运行一次的管理命令填充。该管理命令将删除所有现有密钥并重新添加新数据。我如何确定管理命令是否从django视图运行?有没有办法检查Django管理命令是否正在运行?
现在我正在将管理命令写入外部文件,并让每个请求都有一个读取该文件的视图。如果数据库通过管理命令刷新,我会保持视图直到完成(轮询样式)。
视图依赖于Redis来填充。 Redis由每10分钟运行一次的管理命令填充。该管理命令将删除所有现有密钥并重新添加新数据。我如何确定管理命令是否从django视图运行?有没有办法检查Django管理命令是否正在运行?
现在我正在将管理命令写入外部文件,并让每个请求都有一个读取该文件的视图。如果数据库通过管理命令刷新,我会保持视图直到完成(轮询样式)。
Django不提供预先打包的方式来检查管理命令是否正在运行。这就是说,你永远不应该写代码,在等待某些结果时显式地阻止视图。您可以轻松使用运行应用程序的服务器提供给应用程序的所有线程和进程。您的用户在您的网站上的体验不佳,即使那些与您在此尝试解决的问题没有任何关系的用户也可能遇到困难。
我从你的描述中得到的结果是,你希望用户得到合理的新鲜结果。对于这样的事情,我会使用基于versioning数据的解决方案。它会是这样的:
声明一个Redis的备份缓存在settings.py
文件,将包含由命令填充,由视图读取数据。确保缓存的TIMEOUT
设置为NONE
。
当前版本号与密钥CURRENT_VERSION
一起记录。这个关键本身没有版本。
当命令刷新缓存中的数据时,会将其存储在版本设置为CURRENT_VERSION + 1
的密钥中。你会碰到这样的:
current_version = cache.get(CURRENT_VERSION)
# Record the new data.
for ...:
cache.set(some_key, some_value, version=current_version + 1)
Django的缓存系统不容易允许获得一组对应于特定的标准键。但是,您的视图将希望获取属于特定版本的所有密钥。可以记录这些信息为:
cache.set(ALL_RECORDS,
[... list of keys set in the loop above ...],
version=current_version + 1)
哪里ALL_RECORDS
是保证不会CURRENT_VERSION
或任何对个人记录设置的按键冲突的关键值。
一旦命令完成,它以原子增加CURRENT_VERSION
值:
cache.incr(CURRENT_VERSION)
对Redis的后端的文档指出,如果你在适当的值进行增量(剩下的含糊,但整数似乎适当),那么Redis将以原子方式执行增量。
该命令还应该清理缓存中的旧版本。确保旧数据不会保留在高速缓存中的一种方法是在设置其值时设置密钥的到期时间。刷新缓存的命令每10分钟运行一次。因此,您将密钥设置为在15分钟后过期。但是,假设一个问题阻止了多次运行该命令的运行。然后怎样呢?您的数据将过期并从缓存中删除,并且视图将以空数据集运行。如果这是好您的情况,那么我想你可以在每次做cache.set
,除了CURRENT_VERSION
应该永不过期时间的设置参数timeout
。
如果你不行你的看法有一个空的数据集运行(这似乎更可能对我来说),那么你必须在你的命令,寻求旧版本,并明确地删除它们编写代码。
您的观点通过访问高速缓存:
读的CURRENT_VERSION
值:
keys = cache.get(ALL_RECORDS, version=current_version)
:它得到了版本读取的记录列表 current_version = cache.get(CURRENT_VERSION)
个处理记录:
for key in keys:
value = cache.get(key, version=current_version)
视图应检测其中缓存尚未初始化和优雅地失败的情况。在部署应用程序时,应该注意,在访问站点之前,命令至少运行过一次。
如果视图开始,而命令更新缓存工作,也没关系。从命令的角度来看,缓存只是访问以前的版本。从视图来看,该命令正在忙于创建下一个版本,但这对视图是不可见的。该视图不必阻止。
您希望以检测该命令正在运行,但必须在命令检测到一个视图访问数据? – Louis
不是。该命令不需要知道该信息。只有视图需要知道管理命令是否正在运行。 – ubunix
为什么视图需要知道管理命令是否正在运行? (我有什么样的答案可能是一个想法,但我不想承担。) – Louis