Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
ca77882c
Commit
ca77882c
authored
Mar 16, 2016
by
Saqib
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update static tabs APIs to cache tab contents
parent
af2c6e0e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
143 additions
and
7 deletions
+143
-7
lms/djangoapps/api_manager/courses/content.py
+3
-1
lms/djangoapps/api_manager/courses/tasks.py
+21
-0
lms/djangoapps/api_manager/courses/tests.py
+99
-0
lms/djangoapps/api_manager/courses/views.py
+20
-6
No files found.
lms/djangoapps/api_manager/courses/content.py
View file @
ca77882c
...
@@ -59,7 +59,9 @@ TEST_STATIC_TAB1_CONTENT = dedent(
...
@@ -59,7 +59,9 @@ TEST_STATIC_TAB1_CONTENT = dedent(
TEST_STATIC_TAB2_CONTENT
=
dedent
(
TEST_STATIC_TAB2_CONTENT
=
dedent
(
"""
"""
<div>This is static tab2</div>
<div>
This is static tab2 with content size greater than 200 bytes to test static tab content cache max size limit
</div>
"""
"""
)
)
...
...
lms/djangoapps/api_manager/courses/tasks.py
0 → 100644
View file @
ca77882c
"""
This file contains celery tasks for api_manager courses
"""
import
sys
from
celery.task
import
task
# pylint: disable=import-error,no-name-in-module
from
django.conf
import
settings
from
django.core.cache
import
cache
@task
(
name
=
u'lms.djangoapps.api_manager.courses.tasks.cache_static_tab_content'
)
def
cache_static_tab_contents
(
cache_key
,
contents
):
"""
Caches course static tab contents.
"""
cache_expiration
=
getattr
(
settings
,
'STATIC_TAB_CONTENTS_CACHE_TTL'
,
60
*
5
)
contents_max_size_limit
=
getattr
(
settings
,
'STATIC_TAB_CONTENTS_CACHE_MAX_SIZE_LIMIT'
,
4000
)
if
not
sys
.
getsizeof
(
contents
)
>
contents_max_size_limit
:
cache
.
set
(
cache_key
,
contents
,
cache_expiration
)
lms/djangoapps/api_manager/courses/tests.py
View file @
ca77882c
...
@@ -859,6 +859,24 @@ class CoursesApiTests(ModuleStoreTestCase):
...
@@ -859,6 +859,24 @@ class CoursesApiTests(ModuleStoreTestCase):
self
.
assertEqual
(
tabs
[
1
][
'id'
],
u'readings'
)
self
.
assertEqual
(
tabs
[
1
][
'id'
],
u'readings'
)
self
.
assertEqual
(
tabs
[
1
][
'content'
],
self
.
static_tab2
.
data
)
self
.
assertEqual
(
tabs
[
1
][
'content'
],
self
.
static_tab2
.
data
)
# get syllabus tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tabs
[
0
][
'id'
]
)
tab1_content
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab1_content
is
not
None
)
self
.
assertEqual
(
tab1_content
,
self
.
static_tab1
.
data
)
# get readings tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tabs
[
1
][
'id'
]
)
tab2_content
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab2_content
is
not
None
)
self
.
assertEqual
(
tab2_content
,
self
.
static_tab2
.
data
)
def
test_static_tab_list_get_invalid_course
(
self
):
def
test_static_tab_list_get_invalid_course
(
self
):
#try a bogus course_id to test failure case
#try a bogus course_id to test failure case
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_bogus_course_id
+
'/static_tabs'
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_bogus_course_id
+
'/static_tabs'
...
@@ -874,6 +892,52 @@ class CoursesApiTests(ModuleStoreTestCase):
...
@@ -874,6 +892,52 @@ class CoursesApiTests(ModuleStoreTestCase):
self
.
assertEqual
(
tab
[
'id'
],
u'syllabus'
)
self
.
assertEqual
(
tab
[
'id'
],
u'syllabus'
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab1
.
data
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab1
.
data
)
# now try to get syllabus tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tab
[
'id'
]
)
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
not
None
)
self
.
assertEqual
(
tab_contents
,
self
.
static_tab1
.
data
)
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/static_tabs/readings'
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
tab
=
response
.
data
self
.
assertEqual
(
tab
[
'id'
],
u'readings'
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab2
.
data
)
# now try to get readings tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tab
[
'id'
]
)
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
not
None
)
self
.
assertEqual
(
tab_contents
,
self
.
static_tab2
.
data
)
@override_settings
(
STATIC_TAB_CONTENTS_CACHE_MAX_SIZE_LIMIT
=
200
)
def
test_static_tab_content_cache_max_size_limit
(
self
):
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/static_tabs/syllabus'
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
tab
=
response
.
data
self
.
assertEqual
(
tab
[
'id'
],
u'syllabus'
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab1
.
data
)
# try to get syllabus tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tab
[
'id'
]
)
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
not
None
)
self
.
assertEqual
(
tab_contents
,
self
.
static_tab1
.
data
)
# now test static tab with content size greater than 200 bytes
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/static_tabs/readings'
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/static_tabs/readings'
response
=
self
.
do_get
(
test_uri
)
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
...
@@ -882,6 +946,41 @@ class CoursesApiTests(ModuleStoreTestCase):
...
@@ -882,6 +946,41 @@ class CoursesApiTests(ModuleStoreTestCase):
self
.
assertEqual
(
tab
[
'id'
],
u'readings'
)
self
.
assertEqual
(
tab
[
'id'
],
u'readings'
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab2
.
data
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab2
.
data
)
# try to get readings tab contents from cache
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tab
[
'id'
]
)
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
None
)
@override_settings
(
STATIC_TAB_CONTENTS_CACHE_TTL
=
60
)
def
test_static_tab_content_cache_time_to_live
(
self
):
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/static_tabs/syllabus'
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
tab
=
response
.
data
self
.
assertEqual
(
tab
[
'id'
],
u'syllabus'
)
self
.
assertEqual
(
tab
[
'content'
],
self
.
static_tab1
.
data
)
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
self
.
test_course_id
,
url_slug
=
tab
[
'id'
]
)
# try to get syllabus tab contents from cache
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
not
None
)
self
.
assertEqual
(
tab_contents
,
self
.
static_tab1
.
data
)
# now reset the time to 1 minute and 5 seconds from now in future to expire cache
reset_time
=
datetime
.
now
(
pytz
.
UTC
)
+
timedelta
(
seconds
=
65
)
with
freeze_time
(
reset_time
):
# try to get syllabus tab contents from cache again
tab_contents
=
cache
.
get
(
cache_key
)
self
.
assertTrue
(
tab_contents
is
None
)
def
test_static_tab_detail_get_invalid_course
(
self
):
def
test_static_tab_detail_get_invalid_course
(
self
):
# try a bogus courseId
# try a bogus courseId
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_bogus_course_id
+
'/static_tabs/syllabus'
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_bogus_course_id
+
'/static_tabs/syllabus'
...
...
lms/djangoapps/api_manager/courses/views.py
View file @
ca77882c
...
@@ -10,6 +10,7 @@ from datetime import timedelta
...
@@ -10,6 +10,7 @@ from datetime import timedelta
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
Group
,
User
from
django.contrib.auth.models
import
Group
,
User
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.cache
import
cache
from
django.db.models
import
Avg
,
Count
,
Max
,
Min
from
django.db.models
import
Avg
,
Count
,
Max
,
Min
from
django.http
import
Http404
from
django.http
import
Http404
from
django.utils
import
timezone
from
django.utils
import
timezone
...
@@ -47,6 +48,7 @@ from api_manager.users.serializers import UserSerializer, UserCountByCitySeriali
...
@@ -47,6 +48,7 @@ from api_manager.users.serializers import UserSerializer, UserCountByCitySeriali
from
api_manager.utils
import
generate_base_uri
,
str2bool
,
get_time_series_data
,
parse_datetime
from
api_manager.utils
import
generate_base_uri
,
str2bool
,
get_time_series_data
,
parse_datetime
from
.serializers
import
CourseSerializer
from
.serializers
import
CourseSerializer
from
.serializers
import
GradeSerializer
,
CourseLeadersSerializer
,
CourseCompletionsLeadersSerializer
from
.serializers
import
GradeSerializer
,
CourseLeadersSerializer
,
CourseCompletionsLeadersSerializer
from
.tasks
import
cache_static_tab_contents
from
progress.serializers
import
CourseModuleCompletionSerializer
from
progress.serializers
import
CourseModuleCompletionSerializer
...
@@ -367,6 +369,20 @@ def _get_course_data(request, course_key, course_descriptor, depth=0):
...
@@ -367,6 +369,20 @@ def _get_course_data(request, course_key, course_descriptor, depth=0):
return
data
return
data
def
_get_static_tab_contents
(
request
,
course
,
tab
):
"""
Wrapper around get_static_tab_contents to cache contents for the given static tab
"""
cache_key
=
u'course.{course_id}.static.tab.{url_slug}.contents'
.
format
(
course_id
=
course
.
id
,
url_slug
=
tab
.
url_slug
)
contents
=
cache
.
get
(
cache_key
)
if
contents
is
None
:
contents
=
get_static_tab_contents
(
request
,
course
,
tab
,
wrap_xmodule_display
=
False
)
cache_static_tab_contents
.
delay
(
cache_key
,
contents
)
return
contents
class
CourseContentList
(
SecureAPIView
):
class
CourseContentList
(
SecureAPIView
):
"""
"""
**Use Case**
**Use Case**
...
@@ -912,11 +928,10 @@ class CoursesStaticTabsList(SecureAPIView):
...
@@ -912,11 +928,10 @@ class CoursesStaticTabsList(SecureAPIView):
tab_data
[
'id'
]
=
tab
.
url_slug
tab_data
[
'id'
]
=
tab
.
url_slug
tab_data
[
'name'
]
=
tab
.
name
tab_data
[
'name'
]
=
tab
.
name
if
request
.
GET
.
get
(
'detail'
)
and
request
.
GET
.
get
(
'detail'
)
in
[
'True'
,
'true'
]:
if
request
.
GET
.
get
(
'detail'
)
and
request
.
GET
.
get
(
'detail'
)
in
[
'True'
,
'true'
]:
tab_data
[
'content'
]
=
get_static_tab_contents
(
tab_data
[
'content'
]
=
_
get_static_tab_contents
(
request
,
request
,
course_descriptor
,
course_descriptor
,
tab
,
tab
wrap_xmodule_display
=
False
)
)
tabs
.
append
(
tab_data
)
tabs
.
append
(
tab_data
)
response_data
[
'tabs'
]
=
tabs
response_data
[
'tabs'
]
=
tabs
...
@@ -958,11 +973,10 @@ class CoursesStaticTabsDetail(SecureAPIView):
...
@@ -958,11 +973,10 @@ class CoursesStaticTabsDetail(SecureAPIView):
if
tab
.
type
==
'static_tab'
and
tab
.
url_slug
==
tab_id
:
if
tab
.
type
==
'static_tab'
and
tab
.
url_slug
==
tab_id
:
response_data
[
'id'
]
=
tab
.
url_slug
response_data
[
'id'
]
=
tab
.
url_slug
response_data
[
'name'
]
=
tab
.
name
response_data
[
'name'
]
=
tab
.
name
response_data
[
'content'
]
=
get_static_tab_contents
(
response_data
[
'content'
]
=
_
get_static_tab_contents
(
request
,
request
,
course_descriptor
,
course_descriptor
,
tab
,
tab
wrap_xmodule_display
=
False
)
)
if
not
response_data
:
if
not
response_data
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment