From cae44c7ed9dfdafabc36459efeda54ca17a759d6 Mon Sep 17 00:00:00 2001 From: Ryo Chijiiwa Date: Fri, 5 Feb 2016 23:32:11 -0800 Subject: [PATCH] Revert "global serializer cache" --- .isort.cfg | 1 - dynamic_rest/conf.py | 6 +----- dynamic_rest/fields.py | 21 ++++++++++++--------- install_requires.txt | 1 - tests/test_serializers.py | 6 +++--- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.isort.cfg b/.isort.cfg index 7f3c82de..efc0bdb0 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,3 +1,2 @@ [settings] multi_line_output=3 -known_third_party=django,pylru,rest_framework diff --git a/dynamic_rest/conf.py b/dynamic_rest/conf.py index 4ad438fa..b5267f5c 100644 --- a/dynamic_rest/conf.py +++ b/dynamic_rest/conf.py @@ -32,11 +32,7 @@ # PAGE_SIZE_QUERY_PARAM: global setting for the page size query parameter. # Can be overriden at the viewset level. - 'PAGE_SIZE_QUERY_PARAM': 'per_page', - - # SERIALIZER_CACHE_MAX_COUNT: maximum number of serializers to cache - 'SERIALIZER_CACHE_MAX_COUNT': 1000, - + 'PAGE_SIZE_QUERY_PARAM': 'per_page' } diff --git a/dynamic_rest/fields.py b/dynamic_rest/fields.py index 204ae4ca..d2361ad2 100644 --- a/dynamic_rest/fields.py +++ b/dynamic_rest/fields.py @@ -3,7 +3,6 @@ import importlib import pickle -import pylru from django.utils import six from django.utils.functional import cached_property from rest_framework import fields @@ -14,10 +13,6 @@ from dynamic_rest.conf import settings from dynamic_rest.meta import is_field_remote -serializer_cache = pylru.lrucache( - settings.SERIALIZER_CACHE_MAX_COUNT -) - class DynamicField(fields.Field): @@ -169,10 +164,18 @@ def root_serializer(self): def _get_cached_serializer(self, args, init_args): enabled = settings.ENABLE_SERIALIZER_CACHE - if not self.parent or not self.field_name or not enabled: + root = self.root_serializer + if not root or not self.field_name or not enabled: # Not enough info to use cache. return self.serializer_class(*args, **init_args) + if not hasattr(root, '_descendant_serializer_cache'): + # Initialize dict to use as cache on root serializer. + # Arguably this is a Serializer concern, but we'll do it + # here so it's agnostic to the exact type of the root + # serializer (i.e. it could be a DRF serializer). + root._descendant_serializer_cache = {} + key_dict = { 'parent': self.parent.__class__.__name__, 'field': self.field_name, @@ -181,14 +184,14 @@ def _get_cached_serializer(self, args, init_args): } cache_key = hash(pickle.dumps(key_dict)) - if cache_key not in serializer_cache: + if cache_key not in root._descendant_serializer_cache: szr = self.serializer_class( *args, **init_args ) - serializer_cache[cache_key] = szr + root._descendant_serializer_cache[cache_key] = szr - return serializer_cache[cache_key] + return root._descendant_serializer_cache[cache_key] def _get_request_fields_from_parent(self): """Get request fields from the parent serializer.""" diff --git a/install_requires.txt b/install_requires.txt index 130a4857..94fb3bae 100644 --- a/install_requires.txt +++ b/install_requires.txt @@ -1,3 +1,2 @@ Django>=1.7,<=1.9 djangorestframework>=3.1.0,<=3.3.0 -pylru==1.0.9 diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 4fb00077..f2d13b36 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -647,7 +647,7 @@ def test_same_serializer_class_different_fields(self): ) ) - def test_different_roots_share_cache(self): + def test_different_roots(self): serializer2 = CatSerializer( request_fields={'home': {}, 'backup_home': {}} ) @@ -655,10 +655,10 @@ def test_different_roots_share_cache(self): home1 = self.serializer.fields['home'] home2 = serializer2.fields['home'] - self.assertIs( + self.assertIsNot( home1.serializer, home2.serializer, - 'Different root serializers should share instances.' + 'Different root serializers should yield different instances.' ) def test_root_serializer_cycle_busting(self):