[FIX] registry: use a weak dictionary for model_cache to avoid memory leaks
The class attribute `model_cache` refers to model classes, which refer to their own registry. This cache potentially keeps all past registries alive!
This commit is contained in:
+1
-1
@@ -2817,7 +2817,7 @@ class BaseModel(object):
|
||||
self._add_magic_fields()
|
||||
cls._proper_fields = set(cls._fields)
|
||||
|
||||
cls.pool.model_cache[cls._model_cache_key] = cls
|
||||
cls.pool.model_cache[cls._model_cache_key] = cls
|
||||
|
||||
# 2. add custom fields
|
||||
self._add_manual_fields(partial)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
from collections import Mapping, defaultdict, deque
|
||||
from contextlib import closing
|
||||
from operator import attrgetter
|
||||
from weakref import WeakValueDictionary
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
@@ -30,6 +31,9 @@ class Registry(Mapping):
|
||||
_lock = threading.RLock()
|
||||
_saved_lock = None
|
||||
|
||||
# a cache for model classes, indexed by their base classes
|
||||
model_cache = WeakValueDictionary()
|
||||
|
||||
@lazy_classproperty
|
||||
def registries(cls):
|
||||
""" A mapping from database names to registries. """
|
||||
@@ -177,12 +181,6 @@ class Registry(Mapping):
|
||||
""" Add or replace a model in the registry."""
|
||||
self.models[model_name] = model
|
||||
|
||||
@lazy_classproperty
|
||||
def model_cache(cls):
|
||||
""" A cache for model classes, indexed by their base classes. """
|
||||
# we cache 256 classes per registry on average
|
||||
return LRU(cls.registries.count * 256)
|
||||
|
||||
@lazy_property
|
||||
def field_sequence(self):
|
||||
""" Return a function mapping a field to an integer. The value of a
|
||||
|
||||
Reference in New Issue
Block a user