mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
Make use of caching
This commit is contained in:
@@ -12,11 +12,14 @@ class EventRelatedCache:
|
||||
you store data in this cache, it is only stored for this event. The
|
||||
main purpose of this is to be able to flush all cached data related
|
||||
to this event at once.
|
||||
|
||||
The object is stateless, all state is in the cache, so you can
|
||||
instantiate it as many times as you want.
|
||||
"""
|
||||
|
||||
def __init__(self, event, cache='default'):
|
||||
self.cache = caches[cache]
|
||||
self.prefix = self._build_prefix()
|
||||
self.event = event
|
||||
self.prefixkey = 'event:%d' % self.event.pk
|
||||
|
||||
def _prefix_key(self, original_key):
|
||||
@@ -42,7 +45,7 @@ class EventRelatedCache:
|
||||
prefix = int(time.time())
|
||||
self.cache.set(self.prefixkey, prefix)
|
||||
|
||||
def set(self, key, value, timeout=300):
|
||||
def set(self, key, value, timeout=3600):
|
||||
return self.cache.set(self._prefix_key(key), value, timeout)
|
||||
|
||||
def get(self, key):
|
||||
@@ -51,7 +54,7 @@ class EventRelatedCache:
|
||||
def get_many(self, keys):
|
||||
return self.cache.get_many([self._prefix_key(key) for key in keys])
|
||||
|
||||
def set_many(self, values, timeout=300):
|
||||
def set_many(self, values, timeout=3600):
|
||||
newvalues = {}
|
||||
for i in values.items():
|
||||
newvalues[self._prefix_key(i[0])] = i[1]
|
||||
|
||||
@@ -285,8 +285,9 @@ class Event(models.Model):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
obj = super().save(*args, **kwargs)
|
||||
self.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return obj
|
||||
|
||||
def get_date_from_display(self):
|
||||
return _date(
|
||||
@@ -364,7 +365,7 @@ class ItemCategory(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.event:
|
||||
self.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class Property(models.Model):
|
||||
@@ -393,7 +394,7 @@ class Property(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.event:
|
||||
self.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class PropertyValue(models.Model):
|
||||
@@ -426,7 +427,7 @@ class PropertyValue(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.prop:
|
||||
self.prop.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class Question(models.Model):
|
||||
@@ -472,7 +473,7 @@ class Question(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.event:
|
||||
self.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class Item(models.Model):
|
||||
@@ -560,7 +561,7 @@ class Item(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.event:
|
||||
self.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def delete(self):
|
||||
self.deleted = True
|
||||
@@ -647,7 +648,7 @@ class ItemVariation(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.item:
|
||||
self.item.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class BaseRestriction(models.Model):
|
||||
@@ -679,4 +680,4 @@ class BaseRestriction(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.event:
|
||||
self.event.get_cache().clear()
|
||||
return super().save(self, *args, **kwargs)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
@@ -11,7 +11,7 @@ def availability_handler(sender, **kwargs):
|
||||
# Handle the signal's input arguments
|
||||
item = kwargs['item']
|
||||
variations = kwargs['variations']
|
||||
cache = kwargs['cache'] # NOQA
|
||||
cache = kwargs['cache']
|
||||
context = kwargs['context'] # NOQA
|
||||
|
||||
# Fetch all restriction objects applied to this item
|
||||
@@ -29,6 +29,25 @@ def availability_handler(sender, **kwargs):
|
||||
# interfere with other plugins.
|
||||
variations = [d.copy() for d in variations]
|
||||
|
||||
# The maximum validity of our cached values is the next date, one of our
|
||||
# timeframe_from or tiemframe_to actions happens
|
||||
def timediff(restrictions):
|
||||
for r in restrictions:
|
||||
if r.timeframe_from >= now():
|
||||
yield (r.timeframe_from - now()).total_seconds()
|
||||
if r.timeframe_to >= now():
|
||||
yield (r.timeframe_to - now()).total_seconds()
|
||||
|
||||
try:
|
||||
cache_validity = min(timediff(restrictions))
|
||||
except ValueError:
|
||||
# empty sequence
|
||||
# If we get here, there are restrictions available but nothing will
|
||||
# change about them any more. If it were not for the case of no
|
||||
# restriction for the base item but restrictions for special
|
||||
# variations, we could quit here with 'item not available'.
|
||||
cache_validity = 3600
|
||||
|
||||
# Walk through all variations we are asked for
|
||||
for v in variations:
|
||||
# If this point is reached, there ARE time restrictions for this item
|
||||
@@ -36,6 +55,23 @@ def availability_handler(sender, **kwargs):
|
||||
# without any timeframe
|
||||
available = False
|
||||
price = None
|
||||
|
||||
# Make up some unique key for this variation
|
||||
cachekey = 'timerestriction:%d:%s' % (
|
||||
item.pk,
|
||||
",".join(sorted([str(v[1].pk) for v in v.items() if v[0] != 'variation']))
|
||||
)
|
||||
|
||||
# Fetch from cache, if available
|
||||
cached = cache.get(cachekey)
|
||||
if cached is not None:
|
||||
v['available'] = (cached.split(":")[0] == 'True')
|
||||
try:
|
||||
v['price'] = float(cached.split(":")[1])
|
||||
except ValueError:
|
||||
v['price'] = None
|
||||
continue
|
||||
|
||||
# Walk through all restriction objects applied to this item
|
||||
for restriction in restrictions:
|
||||
applied_to = list(restriction.variations.all())
|
||||
@@ -57,5 +93,10 @@ def availability_handler(sender, **kwargs):
|
||||
|
||||
v['available'] = available
|
||||
v['price'] = price
|
||||
cache.set(
|
||||
cachekey,
|
||||
'%s:%s' % ('True' if available else 'False', str(price) if price else ''),
|
||||
cache_validity
|
||||
)
|
||||
|
||||
return variations
|
||||
|
||||
@@ -33,7 +33,7 @@ class TimeRestrictionTest(TestCase):
|
||||
def test_nothing(self):
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -43,12 +43,13 @@ class TimeRestrictionTest(TestCase):
|
||||
r = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=3),
|
||||
timeframe_to=now() + timedelta(days=3),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -60,12 +61,13 @@ class TimeRestrictionTest(TestCase):
|
||||
r = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() - timedelta(days=3),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -76,18 +78,20 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=3),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=3),
|
||||
timeframe_to=now() + timedelta(days=5),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -99,18 +103,20 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=5),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() + timedelta(days=1),
|
||||
timeframe_to=now() + timedelta(days=7),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -122,18 +128,20 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=2),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() + timedelta(days=4),
|
||||
timeframe_to=now() + timedelta(days=7),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -145,18 +153,20 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() - timedelta(days=1),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() + timedelta(days=4),
|
||||
timeframe_to=now() + timedelta(days=7),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 1)
|
||||
@@ -173,13 +183,14 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=1),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r1.variations.add(v1)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 3)
|
||||
@@ -200,12 +211,14 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=1),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=1),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
@@ -213,13 +226,14 @@ class TimeRestrictionTest(TestCase):
|
||||
r3 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() - timedelta(days=1),
|
||||
event=self.event,
|
||||
price=10
|
||||
)
|
||||
r3.items.add(self.item)
|
||||
r3.variations.add(v2)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 3)
|
||||
@@ -241,6 +255,7 @@ class TimeRestrictionTest(TestCase):
|
||||
r1 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=1),
|
||||
event=self.event,
|
||||
price=12
|
||||
)
|
||||
r1.items.add(self.item)
|
||||
@@ -248,6 +263,7 @@ class TimeRestrictionTest(TestCase):
|
||||
r2 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() + timedelta(days=1),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r2.items.add(self.item)
|
||||
@@ -255,13 +271,14 @@ class TimeRestrictionTest(TestCase):
|
||||
r3 = TimeRestriction.objects.create(
|
||||
timeframe_from=now() - timedelta(days=5),
|
||||
timeframe_to=now() - timedelta(days=1),
|
||||
event=self.event,
|
||||
price=8
|
||||
)
|
||||
r3.items.add(self.item)
|
||||
r3.variations.add(v2)
|
||||
result = signals.availability_handler(
|
||||
None, item=self.item,
|
||||
variations=self.event.get_all_variations(),
|
||||
variations=self.item.get_all_variations(),
|
||||
context=None, cache=self.event.get_cache()
|
||||
)
|
||||
self.assertEqual(len(result), 3)
|
||||
|
||||
Reference in New Issue
Block a user