Commit 3c4252e7 by alawibaba

Merge branch 'release'

parents d7fd454b 5107d463
...@@ -3,6 +3,7 @@ A tiny app that checks for a status message. ...@@ -3,6 +3,7 @@ A tiny app that checks for a status message.
""" """
from django.conf import settings from django.conf import settings
from django.core.cache import cache
import json import json
import logging import logging
import os import os
...@@ -25,6 +26,11 @@ def get_site_status_msg(course_id): ...@@ -25,6 +26,11 @@ def get_site_status_msg(course_id):
not allowed to break the entire site). not allowed to break the entire site).
""" """
try: try:
# first check for msg in cache
msg = cache.get('site_status_msg')
if msg is not None:
return msg
if os.path.isfile(settings.STATUS_MESSAGE_PATH): if os.path.isfile(settings.STATUS_MESSAGE_PATH):
with open(settings.STATUS_MESSAGE_PATH) as f: with open(settings.STATUS_MESSAGE_PATH) as f:
content = f.read() content = f.read()
...@@ -37,6 +43,8 @@ def get_site_status_msg(course_id): ...@@ -37,6 +43,8 @@ def get_site_status_msg(course_id):
msg = msg + "<br>" if msg else '' msg = msg + "<br>" if msg else ''
msg += status_dict[course_id] msg += status_dict[course_id]
# set msg to cache, with expiry 5 mins
cache.set('site_status_msg', msg, 60 * 5)
return msg return msg
except: except:
log.exception("Error while getting a status message.") log.exception("Error while getting a status message.")
......
from django.conf import settings from django.conf import settings
from django.core.cache import cache
from django.test import TestCase from django.test import TestCase
import os import os
from django.test.utils import override_settings from django.test.utils import override_settings
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
import ddt
from .status import get_site_status_msg from .status import get_site_status_msg
...@@ -13,6 +15,7 @@ TMP_NAME = TMP_FILE.name ...@@ -13,6 +15,7 @@ TMP_NAME = TMP_FILE.name
TMP_FILE.close() TMP_FILE.close()
@ddt.ddt
@override_settings(STATUS_MESSAGE_PATH=TMP_NAME) @override_settings(STATUS_MESSAGE_PATH=TMP_NAME)
class TestStatus(TestCase): class TestStatus(TestCase):
"""Test that the get_site_status_msg function does the right thing""" """Test that the get_site_status_msg function does the right thing"""
...@@ -64,6 +67,13 @@ class TestStatus(TestCase): ...@@ -64,6 +67,13 @@ class TestStatus(TestCase):
with open(settings.STATUS_MESSAGE_PATH, 'w') as f: with open(settings.STATUS_MESSAGE_PATH, 'w') as f:
f.write(contents) f.write(contents)
def clear_status_cache(self):
"""
Remove the cached status message, if found
"""
if cache.get('site_status_msg') is not None:
cache.delete('site_status_msg')
def remove_status_file(self): def remove_status_file(self):
"""Delete the status file if it exists""" """Delete the status file if it exists"""
if os.path.exists(settings.STATUS_MESSAGE_PATH): if os.path.exists(settings.STATUS_MESSAGE_PATH):
...@@ -72,18 +82,19 @@ class TestStatus(TestCase): ...@@ -72,18 +82,19 @@ class TestStatus(TestCase):
def tearDown(self): def tearDown(self):
self.remove_status_file() self.remove_status_file()
def test_get_site_status_msg(self): @ddt.data(*checks)
@ddt.unpack
def test_get_site_status_msg(self, json_str, exp_none, exp_toy, exp_full):
"""run the tests""" """run the tests"""
for (json_str, exp_none, exp_toy, exp_full) in self.checks:
self.remove_status_file()
self.remove_status_file() if json_str:
if json_str: self.create_status_file(json_str)
self.create_status_file(json_str)
for course_id, expected_msg in [(None, exp_none), (self.toy_id, exp_toy), (self.full_id, exp_full)]:
print "checking results for {0}".format(json_str) self.assertEqual(get_site_status_msg(course_id), expected_msg)
print "course=None:" self.assertEqual(cache.get('site_status_msg'), expected_msg)
self.assertEqual(get_site_status_msg(None), exp_none) # check that `get_site_status_msg` works as expected when the cache
print "course=toy:" # is warmed, too
self.assertEqual(get_site_status_msg(self.toy_id), exp_toy) self.assertEqual(get_site_status_msg(course_id), expected_msg)
print "course=full:" self.clear_status_cache()
self.assertEqual(get_site_status_msg(self.full_id), exp_full)
...@@ -235,12 +235,15 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers, ...@@ -235,12 +235,15 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
# CDN_VIDEO_URLS is only to be used here and will be deleted # CDN_VIDEO_URLS is only to be used here and will be deleted
# TODO(ali@edx.org): Delete this after the CDN experiment has completed. # TODO(ali@edx.org): Delete this after the CDN experiment has completed.
html_id = self.location.html_id()
if getattr(settings, 'PERFORMANCE_GRAPHITE_URL', '') != '' and \ if getattr(settings, 'PERFORMANCE_GRAPHITE_URL', '') != '' and \
self.system.user_location == 'CN' and \ self.system.user_location == 'CN' and \
getattr(settings, 'ENABLE_VIDEO_BEACON', False) and \ getattr(settings.FEATURES, 'ENABLE_VIDEO_BEACON', False) and \
self.edx_video_id in getattr(settings, 'CDN_VIDEO_URLS', {}).keys(): html_id in getattr(settings, 'CDN_VIDEO_URLS', {}).keys():
cdn_urls = getattr(settings, 'CDN_VIDEO_URLS', {})[self.edx_video_id] cdn_urls = getattr(settings, 'CDN_VIDEO_URLS', {})[html_id]
cdn_exp_group, sources[0] = random.choice(zip(range(len(cdn_urls)), cdn_urls)) cdn_exp_group, new_source = random.choice(zip(range(len(cdn_urls)), cdn_urls))
if cdn_exp_group > 0:
sources[0] = new_source
cdn_eval = True cdn_eval = True
else: else:
cdn_eval = False cdn_eval = False
......
...@@ -554,3 +554,7 @@ FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET") ...@@ -554,3 +554,7 @@ FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET")
FACEBOOK_APP_ID = AUTH_TOKENS.get("FACEBOOK_APP_ID") FACEBOOK_APP_ID = AUTH_TOKENS.get("FACEBOOK_APP_ID")
XBLOCK_SETTINGS = ENV_TOKENS.get('XBLOCK_SETTINGS', {}) XBLOCK_SETTINGS = ENV_TOKENS.get('XBLOCK_SETTINGS', {})
##### CDN EXPERIMENT/MONITORING FLAGS #####
PERFORMANCE_GRAPHITE_URL = ENV_TOKENS.get('PERFORMANCE_GRAPHITE_URL', PERFORMANCE_GRAPHITE_URL)
CDN_VIDEO_URLS = ENV_TOKENS.get('CDN_VIDEO_URLS', CDN_VIDEO_URLS)
...@@ -348,6 +348,9 @@ FEATURES = { ...@@ -348,6 +348,9 @@ FEATURES = {
# log all information from cybersource callbacks # log all information from cybersource callbacks
'LOG_POSTPAY_CALLBACKS': True, 'LOG_POSTPAY_CALLBACKS': True,
# enable beacons for video timing statistics
'ENABLE_VIDEO_BEACON': False,
} }
# Ignore static asset files on import which match this pattern # Ignore static asset files on import which match this pattern
...@@ -2066,6 +2069,10 @@ SEARCH_ENGINE = None ...@@ -2066,6 +2069,10 @@ SEARCH_ENGINE = None
# Use the LMS specific result processor # Use the LMS specific result processor
SEARCH_RESULT_PROCESSOR = "lms.lib.courseware_search.lms_result_processor.LmsSearchResultProcessor" SEARCH_RESULT_PROCESSOR = "lms.lib.courseware_search.lms_result_processor.LmsSearchResultProcessor"
##### CDN EXPERIMENT/MONITORING FLAGS #####
PERFORMANCE_GRAPHITE_URL = ''
CDN_VIDEO_URLS = {}
# The configuration visibility of account fields. # The configuration visibility of account fields.
ACCOUNT_VISIBILITY_CONFIGURATION = { ACCOUNT_VISIBILITY_CONFIGURATION = {
# Default visibility level for accounts without a specified value # Default visibility level for accounts without a specified value
......
...@@ -17,7 +17,7 @@ from status.status import get_site_status_msg ...@@ -17,7 +17,7 @@ from status.status import get_site_status_msg
## Provide a hook for themes to inject branding on top. ## Provide a hook for themes to inject branding on top.
<%block name="navigation_top" /> <%block name="navigation_top" />
<%block cached="False"> <%block>
<% <%
try: try:
course_id = course.id.to_deprecated_string() course_id = course.id.to_deprecated_string()
......
...@@ -17,7 +17,7 @@ from status.status import get_site_status_msg ...@@ -17,7 +17,7 @@ from status.status import get_site_status_msg
## Provide a hook for themes to inject branding on top. ## Provide a hook for themes to inject branding on top.
<%block name="navigation_top" /> <%block name="navigation_top" />
<%block cached="False"> <%block>
<% <%
try: try:
course_id = course.id.to_deprecated_string() course_id = course.id.to_deprecated_string()
......
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
$("#video_${id}").bind("html5:canplaythrough", null, function() { $("#video_${id}").bind("html5:canplaythrough", null, function() {
if (!beaconSent) { if (!beaconSent) {
timeElapsed = Date.now() - cdnStartTime; timeElapsed = Date.now() - cdnStartTime;
sendMetricToGraphite("loadtime_${cdn_exp_group}", timeElapsed); sendMetricToGraphite("videocdnexp.${id}.${cdn_exp_group}.loadtime", timeElapsed);
} }
beaconSent = true; beaconSent = true;
}); });
......
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