Commit d60d6896 by David Ormsbee

Merge performance fixes, and rename StudentModule.get_from_cache to get_with_caching

parents 7f68610d ab0b7910
...@@ -168,17 +168,23 @@ def course_xml_process(tree): ...@@ -168,17 +168,23 @@ def course_xml_process(tree):
return tree return tree
def course_file(user): def course_file(user):
''' Given a user, return course.xml ''' Given a user, return course.xml'''
'''
# TODO: Cache.
filename = user.profile_cache.courseware # UserProfile.objects.get(user=user).courseware filename = user.profile_cache.courseware # UserProfile.objects.get(user=user).courseware
groups = user_groups(user) groups = user_groups(user)
options = {'dev_content':settings.DEV_CONTENT, options = {'dev_content':settings.DEV_CONTENT,
'groups' : groups} 'groups' : groups}
tree = course_xml_process(etree.XML(render_to_string(filename, options, namespace = 'course')))
cache_key = filename + "_processed?dev_content:" + str(options['dev_content']) + "&groups:" + str(sorted(groups))
tree_string = cache.get(cache_key)
if not tree_string:
tree = course_xml_process(etree.XML(render_to_string(filename, options, namespace = 'course')))
tree_string = etree.tostring(tree)
cache.set(cache_key, tree_string, 60)
else:
tree = etree.XML(tree_string)
return tree return tree
def section_file(user, section): def section_file(user, section):
......
...@@ -8,12 +8,19 @@ file and check it in at the same time as your model changes. To do that, ...@@ -8,12 +8,19 @@ file and check it in at the same time as your model changes. To do that,
2. ./manage.py schemamigration courseware --auto description_of_your_change 2. ./manage.py schemamigration courseware --auto description_of_your_change
3. Add the migration file created in mitx/courseware/migrations/ 3. Add the migration file created in mitx/courseware/migrations/
ASSUMPTIONS: modules have unique IDs, even across different module_types
""" """
from django.db import models from django.db import models
from django.db.models.signals import post_save, post_delete
from django.core.cache import cache
from django.contrib.auth.models import User from django.contrib.auth.models import User
from cache_toolbox import cache_model, cache_relation from cache_toolbox import cache_model, cache_relation
CACHE_TIMEOUT = 60 * 60 * 4 # Set the cache timeout to be four hours
class StudentModule(models.Model): class StudentModule(models.Model):
# For a homework problem, contains a JSON # For a homework problem, contains a JSON
# object consisting of state # object consisting of state
...@@ -51,5 +58,35 @@ class StudentModule(models.Model): ...@@ -51,5 +58,35 @@ class StudentModule(models.Model):
def __unicode__(self): def __unicode__(self):
return self.module_type+'/'+self.student.username+"/"+self.module_id+'/'+str(self.state)[:20] return self.module_type+'/'+self.student.username+"/"+self.module_id+'/'+str(self.state)[:20]
@classmethod
def get_with_caching(cls, student, module_id):
k = cls.key_for(student, module_id)
student_module = cache.get(k)
if student_module is None:
student_module = StudentModule.objects.filter(student=student,
module_id=module_id)[0]
# It's possible it really doesn't exist...
if student_module is not None:
cache.set(k, student_module, CACHE_TIMEOUT)
return student_module
@classmethod
def key_for(cls, student, module_id):
return "StudentModule-student_id:{0};module_id:{1}".format(student.id, module_id)
def clear_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
k = sender.key_for(instance.student, instance.module_id)
cache.delete(k)
def update_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
k = sender.key_for(instance.student, instance.module_id)
cache.set(k, instance, CACHE_TIMEOUT)
post_save.connect(update_cache_by_student_and_module_id, sender=StudentModule, weak=False)
post_delete.connect(clear_cache_by_student_and_module_id, sender=StudentModule, weak=False)
cache_model(StudentModule)
cache_model(StudentModule)
\ No newline at end of file
...@@ -48,13 +48,13 @@ def make_track_function(request): ...@@ -48,13 +48,13 @@ def make_track_function(request):
def modx_dispatch(request, module=None, dispatch=None, id=None): def modx_dispatch(request, module=None, dispatch=None, id=None):
''' Generic view for extensions. ''' ''' Generic view for extensions. '''
# Grab the student information for the module from the database # Grab the student information for the module from the database
s = StudentModule.objects.filter(student=request.user, #s = StudentModule.objects.filter(student=request.user,
module_id=id) # module_id=id)
if len(s) == 0: s = StudentModule.get_with_caching(request.user, id)
if s is None:
log.debug("Couldnt find module for user and id " + str(module) + " " + str(request.user) + " "+ str(id)) log.debug("Couldnt find module for user and id " + str(module) + " " + str(request.user) + " "+ str(id))
raise Http404 raise Http404
s=s[0]
oldgrade = s.grade oldgrade = s.grade
oldstate = s.state oldstate = s.state
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment