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
a119b723
Commit
a119b723
authored
Jul 08, 2015
by
Ben McMorran
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TNL-2389 Use discussion id map cache for thread creation and update
parent
8eb0653a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
39 deletions
+84
-39
lms/djangoapps/django_comment_client/base/tests.py
+2
-2
lms/djangoapps/django_comment_client/base/views.py
+5
-12
lms/djangoapps/django_comment_client/forum/tests.py
+4
-4
lms/djangoapps/django_comment_client/tests/test_utils.py
+37
-9
lms/djangoapps/django_comment_client/utils.py
+36
-12
No files found.
lms/djangoapps/django_comment_client/base/tests.py
View file @
a119b723
...
...
@@ -379,7 +379,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
)
self
.
assertEqual
(
response
.
status_code
,
200
)
@patch
(
'django_comment_client.
base.view
s.get_discussion_categories_ids'
,
return_value
=
[
"test_commentable"
])
@patch
(
'django_comment_client.
util
s.get_discussion_categories_ids'
,
return_value
=
[
"test_commentable"
])
def
test_update_thread_wrong_commentable_id
(
self
,
mock_get_discussion_id_map
,
mock_request
):
self
.
_test_request_error
(
"update_thread"
,
...
...
@@ -876,7 +876,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq
self
.
student
=
UserFactory
.
create
()
CourseEnrollmentFactory
(
user
=
self
.
student
,
course_id
=
self
.
course
.
id
)
@patch
(
'django_comment_client.
base.view
s.get_discussion_categories_ids'
,
return_value
=
[
"test_commentable"
])
@patch
(
'django_comment_client.
util
s.get_discussion_categories_ids'
,
return_value
=
[
"test_commentable"
])
@patch
(
'lms.lib.comment_client.utils.requests.request'
)
def
_test_unicode_data
(
self
,
text
,
mock_request
,
mock_get_discussion_id_map
):
self
.
_set_mock_request_data
(
mock_request
,
{
...
...
lms/djangoapps/django_comment_client/base/views.py
View file @
a119b723
...
...
@@ -27,8 +27,7 @@ from django_comment_client.utils import (
JsonResponse
,
prepare_content
,
get_group_id_for_comments_service
,
get_discussion_categories_ids
,
get_discussion_id_map
,
discussion_category_id_access
,
get_cached_discussion_id_map
,
)
from
django_comment_client.permissions
import
check_permissions_by_view
,
has_permission
...
...
@@ -82,7 +81,7 @@ def track_forum_event(request, event_name, course, obj, data, id_map=None):
commentable_id
=
data
[
'commentable_id'
]
if
id_map
is
None
:
id_map
=
get_cached_discussion_id_map
(
course
,
commentable_id
,
user
)
id_map
=
get_cached_discussion_id_map
(
course
,
[
commentable_id
]
,
user
)
if
commentable_id
in
id_map
:
data
[
'category_name'
]
=
id_map
[
commentable_id
][
"title"
]
...
...
@@ -209,14 +208,9 @@ def create_thread(request, course_id, commentable_id):
event_data
=
get_thread_created_event_data
(
thread
,
follow
)
data
=
thread
.
to_dict
()
# Calls to id map are expensive, but we need this more than once.
# Prefetch it.
id_map
=
get_discussion_id_map
(
course
,
request
.
user
)
add_courseware_context
([
data
],
course
,
request
.
user
)
add_courseware_context
([
data
],
course
,
request
.
user
,
id_map
=
id_map
)
track_forum_event
(
request
,
THREAD_CREATED_EVENT_NAME
,
course
,
thread
,
event_data
,
id_map
=
id_map
)
track_forum_event
(
request
,
THREAD_CREATED_EVENT_NAME
,
course
,
thread
,
event_data
)
if
request
.
is_ajax
():
return
ajax_content_response
(
request
,
course_key
,
data
)
...
...
@@ -246,8 +240,7 @@ def update_thread(request, course_id, thread_id):
thread
.
thread_type
=
request
.
POST
[
"thread_type"
]
if
"commentable_id"
in
request
.
POST
:
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
commentable_ids
=
get_discussion_categories_ids
(
course
,
request
.
user
)
if
request
.
POST
.
get
(
"commentable_id"
)
in
commentable_ids
:
if
discussion_category_id_access
(
course
,
request
.
user
,
request
.
POST
.
get
(
"commentable_id"
)):
thread
.
commentable_id
=
request
.
POST
[
"commentable_id"
]
else
:
return
JsonError
(
_
(
"Topic doesn't exist"
))
...
...
lms/djangoapps/django_comment_client/forum/tests.py
View file @
a119b723
...
...
@@ -317,11 +317,11 @@ class SingleThreadQueryCountTestCase(ModuleStoreTestCase):
@ddt.data
(
# old mongo with cache
(
ModuleStoreEnum
.
Type
.
mongo
,
1
,
7
,
5
,
1
2
,
7
),
(
ModuleStoreEnum
.
Type
.
mongo
,
50
,
7
,
5
,
1
2
,
7
),
(
ModuleStoreEnum
.
Type
.
mongo
,
1
,
7
,
5
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
mongo
,
50
,
7
,
5
,
1
3
,
8
),
# split mongo: 3 queries, regardless of thread response size.
(
ModuleStoreEnum
.
Type
.
split
,
1
,
3
,
3
,
1
2
,
7
),
(
ModuleStoreEnum
.
Type
.
split
,
50
,
3
,
3
,
1
2
,
7
),
(
ModuleStoreEnum
.
Type
.
split
,
1
,
3
,
3
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
split
,
50
,
3
,
3
,
1
3
,
8
),
)
@ddt.unpack
def
test_number_of_mongo_queries
(
...
...
lms/djangoapps/django_comment_client/tests/test_utils.py
View file @
a119b723
...
...
@@ -170,6 +170,13 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
discussion_category
=
'Chapter'
,
discussion_target
=
'Discussion 1'
)
self
.
discussion2
=
ItemFactory
.
create
(
parent_location
=
self
.
course
.
location
,
category
=
'discussion'
,
discussion_id
=
'test_discussion_id_2'
,
discussion_category
=
'Chapter 2'
,
discussion_target
=
'Discussion 2'
)
self
.
private_discussion
=
ItemFactory
.
create
(
parent_location
=
self
.
course
.
location
,
category
=
'discussion'
,
...
...
@@ -212,11 +219,18 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
self
.
assertFalse
(
utils
.
has_required_keys
(
self
.
bad_discussion
))
def
verify_discussion_metadata
(
self
):
"""Retrieves the metadata for self.discussion and verifies that it is correct"""
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
'test_discussion_id'
,
self
.
user
)
metadata
=
metadata
[
self
.
discussion
.
discussion_id
]
self
.
assertEqual
(
metadata
[
'location'
],
self
.
discussion
.
location
)
self
.
assertEqual
(
metadata
[
'title'
],
'Chapter / Discussion 1'
)
"""Retrieves the metadata for self.discussion and self.discussion2 and verifies that it is correct"""
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
[
'test_discussion_id'
,
'test_discussion_id_2'
],
self
.
user
)
discussion1
=
metadata
[
self
.
discussion
.
discussion_id
]
discussion2
=
metadata
[
self
.
discussion2
.
discussion_id
]
self
.
assertEqual
(
discussion1
[
'location'
],
self
.
discussion
.
location
)
self
.
assertEqual
(
discussion1
[
'title'
],
'Chapter / Discussion 1'
)
self
.
assertEqual
(
discussion2
[
'location'
],
self
.
discussion2
.
location
)
self
.
assertEqual
(
discussion2
[
'title'
],
'Chapter 2 / Discussion 2'
)
def
test_get_discussion_id_map_from_cache
(
self
):
self
.
verify_discussion_metadata
()
...
...
@@ -226,22 +240,36 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
self
.
verify_discussion_metadata
()
def
test_get_missing_discussion_id_map_from_cache
(
self
):
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
'bogus_id'
,
self
.
user
)
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
[
'bogus_id'
]
,
self
.
user
)
self
.
assertEqual
(
metadata
,
{})
def
test_get_discussion_id_map_from_cache_without_access
(
self
):
user
=
UserFactory
.
create
()
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
'private_discussion_id'
,
self
.
user
)
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
[
'private_discussion_id'
]
,
self
.
user
)
self
.
assertEqual
(
metadata
[
'private_discussion_id'
][
'title'
],
'Chapter 3 / Beta Testing'
)
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
'private_discussion_id'
,
user
)
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
[
'private_discussion_id'
]
,
user
)
self
.
assertEqual
(
metadata
,
{})
def
test_get_bad_discussion_id
(
self
):
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
'bad_discussion_id'
,
self
.
user
)
metadata
=
utils
.
get_cached_discussion_id_map
(
self
.
course
,
[
'bad_discussion_id'
]
,
self
.
user
)
self
.
assertEqual
(
metadata
,
{})
def
test_discussion_id_accessible
(
self
):
self
.
assertTrue
(
utils
.
discussion_category_id_access
(
self
.
course
,
self
.
user
,
'test_discussion_id'
))
def
test_bad_discussion_id_not_accessible
(
self
):
self
.
assertFalse
(
utils
.
discussion_category_id_access
(
self
.
course
,
self
.
user
,
'bad_discussion_id'
))
def
test_missing_discussion_id_not_accessible
(
self
):
self
.
assertFalse
(
utils
.
discussion_category_id_access
(
self
.
course
,
self
.
user
,
'bogus_id'
))
def
test_discussion_id_not_accessible_without_access
(
self
):
user
=
UserFactory
.
create
()
self
.
assertTrue
(
utils
.
discussion_category_id_access
(
self
.
course
,
self
.
user
,
'private_discussion_id'
))
self
.
assertFalse
(
utils
.
discussion_category_id_access
(
self
.
course
,
user
,
'private_discussion_id'
))
class
CategoryMapTestMixin
(
object
):
"""
...
...
lms/djangoapps/django_comment_client/utils.py
View file @
a119b723
...
...
@@ -118,19 +118,22 @@ def get_cached_discussion_key(course, discussion_id):
raise
DiscussionIdMapIsNotCached
()
def
get_cached_discussion_id_map
(
course
,
discussion_id
,
user
):
def
get_cached_discussion_id_map
(
course
,
discussion_id
s
,
user
):
"""
Returns a dict mapping discussion_id
to discussion module metadata if it is cached and visible to the user.
If not, returns the result of get_discussion_id_map
Returns a dict mapping discussion_id
s to respective discussion module metadata if it is cached and visible to the
user.
If not, returns the result of get_discussion_id_map
"""
try
:
key
=
get_cached_discussion_key
(
course
,
discussion_id
)
if
not
key
:
return
{}
module
=
modulestore
()
.
get_item
(
key
)
if
not
(
has_required_keys
(
module
)
and
has_access
(
user
,
'load'
,
module
,
course
.
id
)):
return
{}
return
dict
([
get_discussion_id_map_entry
(
module
)])
entries
=
[]
for
discussion_id
in
discussion_ids
:
key
=
get_cached_discussion_key
(
course
,
discussion_id
)
if
not
key
:
continue
module
=
modulestore
()
.
get_item
(
key
)
if
not
(
has_required_keys
(
module
)
and
has_access
(
user
,
'load'
,
module
,
course
.
id
)):
continue
entries
.
append
(
get_discussion_id_map_entry
(
module
))
return
dict
(
entries
)
except
DiscussionIdMapIsNotCached
:
return
get_discussion_id_map
(
course
,
user
)
...
...
@@ -324,6 +327,23 @@ def get_discussion_category_map(course, user, cohorted_if_in_list=False, exclude
return
_filter_unstarted_categories
(
category_map
)
if
exclude_unstarted
else
category_map
def
discussion_category_id_access
(
course
,
user
,
discussion_id
):
"""
Returns True iff the given discussion_id is accessible for user in course. Uses the discussion id cache if available
falling back to get_discussion_categories_ids if there is no cache.
"""
if
discussion_id
in
course
.
top_level_discussion_topic_ids
:
return
True
try
:
key
=
get_cached_discussion_key
(
course
,
discussion_id
)
if
not
key
:
return
False
module
=
modulestore
()
.
get_item
(
key
)
return
has_required_keys
(
module
)
and
has_access
(
user
,
'load'
,
module
,
course
.
id
)
except
DiscussionIdMapIsNotCached
:
return
discussion_id
in
get_discussion_categories_ids
(
course
,
user
)
def
get_discussion_categories_ids
(
course
,
user
,
include_all
=
False
):
"""
Returns a list of available ids of categories for the course that
...
...
@@ -490,10 +510,14 @@ def extend_content(content):
def
add_courseware_context
(
content_list
,
course
,
user
,
id_map
=
None
):
"""
Decorates `content_list` with courseware metadata.
Decorates `content_list` with courseware metadata
using the discussion id map cache if available
.
"""
if
id_map
is
None
:
id_map
=
get_discussion_id_map
(
course
,
user
)
id_map
=
get_cached_discussion_id_map
(
course
,
[
content
[
'commentable_id'
]
for
content
in
content_list
],
user
)
for
content
in
content_list
:
commentable_id
=
content
[
'commentable_id'
]
...
...
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