django中的类和实例变量的生命周期和范围

时间:2016-12-20 02:56:22

标签: django python-2.7

虽然这里已经有很多关于python中不同变量生命的问题和答案,但我正在寻找它们如何在应用程序范围和端点范围方面转换为django环境。这是我正在制作的一个简单版本,我想确保它的行为方式与我期待的一样

my_cache /模型/ GlobalCache.py:

# This class should be global to the entire application and only
# load when the server is started.

class GlobalCacheobject):
    _cache = {}

    @classmethod
    def fetch(cls):
        return cls._cache

    @classmethod
    def flush(cls):
        cls._cache = {}

    @classmethod
    def load_cache(cls, files_to_load_data_from):
        for file in files_to_load_from:
            cls._cache[file] = <load file and process its data into an entry>

my_cache /模型/ InstanceCache.py:

from .GlobalCache import GlobalCache

# This class will contain a reference to the global cache and use it to look
# up entries.

class InstanceCache(object):
    def __init__(self, name=None):
        self._name = name
        self._cache = GlobalCache.fetch()

    def fetch_file_data(self, file_name):
        cache_entry = self._cache.get(file_name, None)
        if cache_entry is None:
            raise EntryNotFoundException()
        return ReadOnlyInterfaceObject(cache_entry)

目的是让GlobalCache具有cls._cache值,只要服务器正在运行,该值就会持续存在。调用GlobalCache.flush()将删除其对其跟踪的数据的全局引用,并且调用GlobalCache.load(files_to_load_from)将填充其数据的新实例。

然后,InstanceCache对象用于保存对当前数据版本的引用,并返回由其原始文件名标识的不同数据集的只读对象。

从我的测试中看起来似乎有用,但我本身并没有真正拥有InstanceCache对象。我可以加载全局缓存,检索只读对象,然后刷新全局,用新数据加载它。原始只读对象仍然返回它们最初加载的值,新请求将使用新数据值。

我想确认的是,只要服务器正在运行,GlobalCache就会存在,并且只能通过直接调用flush()和load_cache()来改变其数据。当我点击一个端点并创建一个InstanceCache时,只要它存在,它就会保留对原始数据的引用。当终点上的执行完成后,我希望它超出范围,删除对全局缓存的引用,如果这是最后一个,它就会消失,只保留新的/当前数据。如果重要,我正在运行Python 2.7.6和django 1.5.12。需要升级的解决方案也可能有用,但对我来说不是一个直接的选择。

1 个答案:

答案 0 :(得分:2)

这里的答案可能是,这也很大程度上取决于您使用哪个app服务器来运行django(如果您正在运行多进程)。

因此,一般来说,是的,InstanceCache将在其初始化后的进程的生命周期内保留其缓存内容。

但另一方面,GlobalCache只能保证在没有更多引用之后的某个时间进行垃圾回收。垃圾收集是一个很深的领域,并且通常有许多团队负责算法,因此进入确切的场景可能超出了SO的答案范围。一个流行的python实现是pypy,你可以阅读更多有关pypy here中使用的垃圾收集的信息。

那就是说,请记住,大多数应用服务器都是多进程的。 uwsgi和gunicorn都会启动子进程来处理请求。因此即使GlobalCache在其进程中是一个单例,也可能有多个进程,每个进程都有自己的GlobalCache。并且,当进程退出时,此<svg> <defs> <pattern id="bustop_icon" x="0" y="0" width="18" height="18"> <image xlink:href="img/images/bus-icon.png" x="3" y="5" width="18" height="20" /> </pattern> </defs> </svg> 最终将被垃圾收集/清理。在子服务一些HTTP请求之后,uwsgi和gunicorn通常会杀死子进程。