2016-12-20 2 views
0

Хотя здесь уже много вопросов и ответов о жизни разных переменных в python, я ищу, как они переходят в среду django с точки зрения сферы применения и конечных точек. Вот простой вариант того, что я делаю, и я хочу, чтобы убедиться, что он будет вести себя так, как я ожидал, что этоСрок службы и объем переменных класса и экземпляра в 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. Решения, требующие обновления, могут быть полезны, но это не является непосредственной возможностью для меня.

ответ

2

Ответ здесь может быть, и это также сильно зависит от того, какой сервер приложений вы используете для запуска django (если вы используете многопроцессорный процесс).

Так что, вообще говоря, да, GlobalCache сохранит свое кэшированное содержимое для времени жизни процесса, в котором он находится после того, как он был инициализирован.

Но, с другой стороны, InstanceCache гарантированно будет собирать мусор после того, как на нем больше нет ссылок. Сбор мусора - это глубокое поле, и часто команды людей, которые работают над алгоритмами, поэтому вхождение в точные сценарии, вероятно, выходит за рамки ответа на SO. Популярная реализация python - pypy, и вы можете больше узнать о сборке мусора, который используется в pypy here.

Это, пожалуйста, помните, что большинство серверов приложений являются многопроцессорными. Оба uwsgi и gunicorn разворачивают дочерние процессы для обслуживания запросов. Таким образом, хотя GlobalCache является одним тоннелем в своем процессе, может быть несколько процессов, каждый со своим собственным GlobalCache. И этот GlobalCache в конечном итоге будет собираться/очищаться от мусора, когда процесс завершается. Как uwsgi, так и gunicorn, как правило, убивают дочерние процессы после того, как ребенок обслуживает некоторое количество HTTP-запросов.

+0

Хорошая информация ..Не будет ли у детей процессов иметь собственную версию «GlobalCache», которая будет создана и уничтожена, когда они будут развернуты вверх и вниз? И я в порядке, просто оставив его по номиналу «когда будет сделан сбор мусора», это будет тогда «аспект» его жизненного времени. Я просто беспокоился о том, чтобы оставить что-то, чтобы память просачивалась и никогда не помечена для сбора. – James

+0

Да, «GlobalCache» будет процессом singleton и будет выполняться один раз в процессе. Хорошей частью серверов приложений является то, что даже если есть утечка памяти, процесс будет умирать после N запросов. Не идеально, но по крайней мере это помогает. – 2ps

Смежные вопросы