Navigation Menu

Skip to content

Commit

Permalink
Caching for allowed_schema_ids, for performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
slinkp committed Nov 29, 2011
1 parent 94d3182 commit 4f9f411
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
3 changes: 3 additions & 0 deletions ebpub/ebpub/db/constants.py
Expand Up @@ -43,3 +43,6 @@
# the optional pre-directional and/or post-directional (for example,
# 'n', 'ne', 'n-w', '-sw').
BLOCK_URL_REGEX = r'(\d{1,6})-(\d{1,6})([nsew]{1,2})?(?:-([nsew]{0,2}))?'

# How long the Schema managers should cache allowed_schema_ids()
ALLOWED_IDS_CACHE_TIME = 60 * 10
41 changes: 39 additions & 2 deletions ebpub/ebpub/db/models.py
Expand Up @@ -20,8 +20,10 @@
from django.contrib.gis.db import models
from django.contrib.gis.db.models import Count
from django.core import urlresolvers
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.db import connection, transaction
from ebpub.db import constants
from ebpub.geocoder.parser.parsing import normalize
from ebpub.utils.geodjango import flatten_geomcollection
from ebpub.utils.geodjango import ensure_valid
Expand Down Expand Up @@ -69,6 +71,16 @@ def field_mapping(schema_id_list):

class SchemaManager(models.Manager):

_allowed_ids_cache_key = 'allowed_schema_ids__all'

def update(self, *args, **kwargs):
# Django doesn't provide pre/post_update signals, rats.
# See https://code.djangoproject.com/ticket/13021
# So we define one and send it here.
result = super(SchemaManager, self).update(*args, **kwargs)
post_update.send(sender=Schema)
return result

def get_by_natural_key(self, slug):
return self.get(slug=slug)

Expand All @@ -93,11 +105,16 @@ def allowed_schema_ids(self):
Useful for filtering out schemas (or things related to
schemas) based on the current Manager.
"""
return [s['id'] for s in self.all().values('id')]

ids = cache.get(self._allowed_ids_cache_key, None)
if ids is None:
ids = [s['id'] for s in self.all().values('id')]
cache.set(self._allowed_ids_cache_key, ids, constants.ALLOWED_IDS_CACHE_TIME)
return ids

class SchemaPublicManager(SchemaManager):

_allowed_ids_cache_key = 'allowed_schema_ids__public'

def get_query_set(self):
return super(SchemaManager, self).get_query_set().filter(is_public=True)

Expand Down Expand Up @@ -1164,3 +1181,23 @@ def get_city_locations():
return cities
else:
return Location.objects.filter(id=None)


########################################################################
# Signals

# Django doesn't provide a pre_update() signal, rats.
# See https://code.djangoproject.com/ticket/13021
from django.dispatch import Signal
from django.db.models.signals import post_save, post_delete

post_update = Signal(providing_args=[])

def clear_allowed_schema_ids_cache(sender, **kwargs):
cache.delete_many((SchemaPublicManager._allowed_ids_cache_key,
SchemaManager._allowed_ids_cache_key))

post_update.connect(clear_allowed_schema_ids_cache, sender=Schema)
post_save.connect(clear_allowed_schema_ids_cache, sender=Schema)
post_delete.connect(clear_allowed_schema_ids_cache, sender=Schema)

1 change: 1 addition & 0 deletions ebpub/ebpub/db/tests/test_models.py
Expand Up @@ -216,6 +216,7 @@ def test_top_lookups__m2m(self):
self.assertEqual(top_lookups[1]['count'], 2)
self.assertEqual(top_lookups[1]['lookup'].slug, u'tag-2')


def test_allowed_schema_ids(self):
from ebpub.db.models import Schema
self.assertEqual(Schema.objects.allowed_schema_ids(),
Expand Down

0 comments on commit 4f9f411

Please sign in to comment.