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
b609a969
Commit
b609a969
authored
Mar 27, 2013
by
Chris Dodge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ummm. forgot to commit stuff
parent
03f9bb5d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
106 deletions
+64
-106
cms/envs/common.py
+1
-0
cms/one_time_startup.py
+3
-1
common/lib/xmodule/xmodule/modulestore/mongo.py
+56
-49
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
+0
-55
lms/envs/common.py
+1
-0
lms/one_time_startup.py
+3
-1
No files found.
cms/envs/common.py
View file @
b609a969
...
@@ -113,6 +113,7 @@ TEMPLATE_LOADERS = (
...
@@ -113,6 +113,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES
=
(
MIDDLEWARE_CLASSES
=
(
'contentserver.middleware.StaticContentServer'
,
'contentserver.middleware.StaticContentServer'
,
'request_cache.middleware.RequestCache'
,
'django.middleware.cache.UpdateCacheMiddleware'
,
'django.middleware.cache.UpdateCacheMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
...
...
cms/one_time_startup.py
View file @
b609a969
from
dogapi
import
dog_http_api
,
dog_stats_api
from
dogapi
import
dog_http_api
,
dog_stats_api
from
django.conf
import
settings
from
django.conf
import
settings
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
request_cache.middleware
import
RequestCache
from
django.core.cache
import
get_cache
,
InvalidCacheBackendError
from
django.core.cache
import
get_cache
,
InvalidCacheBackendError
cache
=
get_cache
(
'mongo_metadata_inheritance'
)
cache
=
get_cache
(
'mongo_metadata_inheritance'
)
for
store_name
in
settings
.
MODULESTORE
:
for
store_name
in
settings
.
MODULESTORE
:
store
=
modulestore
(
store_name
)
store
=
modulestore
(
store_name
)
store
.
metadata_inheritance_cache
=
cache
store
.
metadata_inheritance_cache_subsystem
=
cache
store
.
request_cache
=
RequestCache
.
get_request_cache
()
if
hasattr
(
settings
,
'DATADOG_API'
):
if
hasattr
(
settings
,
'DATADOG_API'
):
dog_http_api
.
api_key
=
settings
.
DATADOG_API
dog_http_api
.
api_key
=
settings
.
DATADOG_API
...
...
common/lib/xmodule/xmodule/modulestore/mongo.py
View file @
b609a969
...
@@ -27,6 +27,9 @@ from .inheritance import own_metadata, INHERITABLE_METADATA, inherit_metadata
...
@@ -27,6 +27,9 @@ from .inheritance import own_metadata, INHERITABLE_METADATA, inherit_metadata
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
import
threading
_mongo_metadata_request_cache_threadlocal
=
threading
.
local
()
# TODO (cpennington): This code currently operates under the assumption that
# TODO (cpennington): This code currently operates under the assumption that
# there is only one revision for each item. Once we start versioning inside the CMS,
# there is only one revision for each item. Once we start versioning inside the CMS,
# that assumption will have to change
# that assumption will have to change
...
@@ -109,7 +112,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -109,7 +112,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
references to metadata_inheritance_tree
references to metadata_inheritance_tree
"""
"""
def
__init__
(
self
,
modulestore
,
module_data
,
default_class
,
resources_fs
,
def
__init__
(
self
,
modulestore
,
module_data
,
default_class
,
resources_fs
,
error_tracker
,
render_template
,
metadata_cache
=
None
):
error_tracker
,
render_template
,
cached_metadata
=
None
):
"""
"""
modulestore: the module store that can be used to retrieve additional modules
modulestore: the module store that can be used to retrieve additional modules
...
@@ -134,7 +137,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -134,7 +137,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
# cdodge: other Systems have a course_id attribute defined. To keep things consistent, let's
# cdodge: other Systems have a course_id attribute defined. To keep things consistent, let's
# define an attribute here as well, even though it's None
# define an attribute here as well, even though it's None
self
.
course_id
=
None
self
.
course_id
=
None
self
.
metadata_cache
=
metadata_cache
self
.
cached_metadata
=
cached_metadata
def
load_item
(
self
,
location
):
def
load_item
(
self
,
location
):
"""
"""
...
@@ -170,8 +174,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -170,8 +174,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
model_data
=
DbModel
(
kvs
,
class_
,
None
,
MongoUsage
(
self
.
course_id
,
location
))
model_data
=
DbModel
(
kvs
,
class_
,
None
,
MongoUsage
(
self
.
course_id
,
location
))
module
=
class_
(
self
,
location
,
model_data
)
module
=
class_
(
self
,
location
,
model_data
)
if
self
.
metadata_cache
is
not
None
:
if
self
.
cached_metadata
is
not
None
:
metadata_to_inherit
=
self
.
metadata_cache
.
get
(
metadata_cache_key
(
location
),
{})
.
get
(
'parent_metadata'
,
{})
.
get
(
location
.
url
(),
{})
metadata_to_inherit
=
self
.
cached_metadata
.
get
(
location
.
url
(),
{})
inherit_metadata
(
module
,
metadata_to_inherit
)
inherit_metadata
(
module
,
metadata_to_inherit
)
return
module
return
module
except
:
except
:
...
@@ -223,7 +227,8 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -223,7 +227,8 @@ class MongoModuleStore(ModuleStoreBase):
def
__init__
(
self
,
host
,
db
,
collection
,
fs_root
,
render_template
,
def
__init__
(
self
,
host
,
db
,
collection
,
fs_root
,
render_template
,
port
=
27017
,
default_class
=
None
,
port
=
27017
,
default_class
=
None
,
error_tracker
=
null_error_tracker
,
error_tracker
=
null_error_tracker
,
user
=
None
,
password
=
None
,
**
kwargs
):
user
=
None
,
password
=
None
,
request_cache
=
None
,
metadata_inheritance_cache_subsystem
=
None
,
**
kwargs
):
ModuleStoreBase
.
__init__
(
self
)
ModuleStoreBase
.
__init__
(
self
)
...
@@ -254,8 +259,10 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -254,8 +259,10 @@ class MongoModuleStore(ModuleStoreBase):
self
.
error_tracker
=
error_tracker
self
.
error_tracker
=
error_tracker
self
.
render_template
=
render_template
self
.
render_template
=
render_template
self
.
ignore_write_events_on_courses
=
[]
self
.
ignore_write_events_on_courses
=
[]
self
.
request_cache
=
request_cache
self
.
metadata_inheritance_cache_subsystem
=
metadata_inheritance_cache_subsystem
def
get
_metadata_inheritance_tree
(
self
,
location
):
def
compute
_metadata_inheritance_tree
(
self
,
location
):
'''
'''
TODO (cdodge) This method can be deleted when the 'split module store' work has been completed
TODO (cdodge) This method can be deleted when the 'split module store' work has been completed
'''
'''
...
@@ -323,32 +330,47 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -323,32 +330,47 @@ class MongoModuleStore(ModuleStoreBase):
if
root
is
not
None
:
if
root
is
not
None
:
_compute_inherited_metadata
(
root
)
_compute_inherited_metadata
(
root
)
return
{
'parent_metadata'
:
metadata_to_inherit
,
return
metadata_to_inherit
'timestamp'
:
datetime
.
now
()}
def
get_cached_metadata_inheritance_tree
s
(
self
,
locations
,
force_refresh
=
False
):
def
get_cached_metadata_inheritance_tree
(
self
,
location
,
force_refresh
=
False
):
'''
'''
TODO (cdodge) This method can be deleted when the 'split module store' work has been completed
TODO (cdodge) This method can be deleted when the 'split module store' work has been completed
'''
'''
key
=
metadata_cache_key
(
location
)
tree
=
{}
if
not
force_refresh
:
# see if we are first in the request cache (if present)
if
self
.
request_cache
is
not
None
and
key
in
self
.
request_cache
.
data
.
get
(
'metadata_inheritance'
,
{}):
logging
.
debug
(
'***** HIT IN REQUEST CACHE'
)
return
self
.
request_cache
.
data
[
'metadata_inheritance'
][
key
]
# then look in any caching subsystem (e.g. memcached)
if
self
.
metadata_inheritance_cache_subsystem
is
not
None
:
tree
=
self
.
metadata_inheritance_cache_subsystem
.
get
(
key
,
{})
if
tree
:
logging
.
debug
(
'***** HIT IN MEMCACHED'
)
else
:
logging
.
warning
(
'Running MongoModuleStore without a metadata_inheritance_cache_subsystem. This is OK in localdev and testing environment. Not OK in production.'
)
trees
=
{}
if
not
tree
:
if
locations
and
self
.
metadata_inheritance_cache
is
not
None
and
not
force_refresh
:
# if not in subsystem, or we are on force refresh, then we have to compute
trees
=
self
.
metadata_inheritance_cache
.
get_many
(
list
(
set
([
metadata_cache_key
(
loc
)
for
loc
in
locations
])))
logging
.
debug
(
'***** COMPUTING METADATA'
)
else
:
tree
=
self
.
compute_metadata_inheritance_tree
(
location
)
# This is to help guard against an accident prod runtime without a cache
logging
.
warning
(
'Running MongoModuleStore without metadata_inheritance_cache. '
'This should not happen in production!'
)
to_cache
=
{}
# now populate a request_cache, if available
for
loc
in
locations
:
if
self
.
request_cache
is
not
None
:
cache_key
=
metadata_cache_key
(
loc
)
# we can't assume the 'metadatat_inheritance' part of the request cache dict has been
if
cache_key
not
in
trees
:
# defined
to_cache
[
cache_key
]
=
trees
[
cache_key
]
=
self
.
get_metadata_inheritance_tree
(
loc
)
if
'metadata_inheritance'
not
in
self
.
request_cache
.
data
:
self
.
request_cache
.
data
[
'metadata_inheritance'
]
=
{}
self
.
request_cache
.
data
[
'metadata_inheritance'
][
key
]
=
tree
if
to_cache
and
self
.
metadata_inheritance_cache
is
not
None
:
# now write to caching subsystem (e.g. memcached), if available
self
.
metadata_inheritance_cache
.
set_many
(
to_cache
)
if
self
.
metadata_inheritance_cache_subsystem
is
not
None
:
self
.
metadata_inheritance_cache_subsystem
.
set
(
key
,
tree
)
return
tree
s
return
tree
def
refresh_cached_metadata_inheritance_tree
(
self
,
location
):
def
refresh_cached_metadata_inheritance_tree
(
self
,
location
):
"""
"""
...
@@ -357,15 +379,7 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -357,15 +379,7 @@ class MongoModuleStore(ModuleStoreBase):
"""
"""
pseudo_course_id
=
'/'
.
join
([
location
.
org
,
location
.
course
])
pseudo_course_id
=
'/'
.
join
([
location
.
org
,
location
.
course
])
if
pseudo_course_id
not
in
self
.
ignore_write_events_on_courses
:
if
pseudo_course_id
not
in
self
.
ignore_write_events_on_courses
:
self
.
get_cached_metadata_inheritance_trees
([
location
],
force_refresh
=
True
)
self
.
get_cached_metadata_inheritance_tree
(
location
,
force_refresh
=
True
)
def
clear_cached_metadata_inheritance_tree
(
self
,
location
):
"""
Delete the cached metadata inheritance tree for the org/course combination
for location
"""
if
self
.
metadata_inheritance_cache
is
not
None
:
self
.
metadata_inheritance_cache
.
delete
(
metadata_cache_key
(
location
))
def
_clean_item_data
(
self
,
item
):
def
_clean_item_data
(
self
,
item
):
"""
"""
...
@@ -411,18 +425,7 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -411,18 +425,7 @@ class MongoModuleStore(ModuleStoreBase):
return
data
return
data
def
_cache_metadata_inheritance
(
self
,
items
,
depth
,
force_refresh
=
False
):
def
_load_item
(
self
,
item
,
data_cache
,
apply_cached_metadata
=
True
):
"""
Retrieves all course metadata inheritance trees needed to load items
"""
locations
=
[
Location
(
item
[
'location'
])
for
item
in
items
if
not
(
item
[
'location'
][
'category'
]
==
'course'
and
depth
==
0
)
]
return
self
.
get_cached_metadata_inheritance_trees
(
locations
,
force_refresh
=
force_refresh
)
def
_load_item
(
self
,
item
,
data_cache
,
metadata_cache
):
"""
"""
Load an XModuleDescriptor from item, using the children stored in data_cache
Load an XModuleDescriptor from item, using the children stored in data_cache
"""
"""
...
@@ -434,6 +437,10 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -434,6 +437,10 @@ class MongoModuleStore(ModuleStoreBase):
resource_fs
=
OSFS
(
root
)
resource_fs
=
OSFS
(
root
)
cached_metadata
=
{}
if
apply_cached_metadata
:
cached_metadata
=
self
.
get_cached_metadata_inheritance_tree
(
Location
(
item
[
'location'
]))
# TODO (cdodge): When the 'split module store' work has been completed, we should remove
# TODO (cdodge): When the 'split module store' work has been completed, we should remove
# the 'metadata_inheritance_tree' parameter
# the 'metadata_inheritance_tree' parameter
system
=
CachingDescriptorSystem
(
system
=
CachingDescriptorSystem
(
...
@@ -443,7 +450,7 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -443,7 +450,7 @@ class MongoModuleStore(ModuleStoreBase):
resource_fs
,
resource_fs
,
self
.
error_tracker
,
self
.
error_tracker
,
self
.
render_template
,
self
.
render_template
,
metadata_cache
,
cached_metadata
,
)
)
return
system
.
load_item
(
item
[
'location'
])
return
system
.
load_item
(
item
[
'location'
])
...
@@ -453,11 +460,11 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -453,11 +460,11 @@ class MongoModuleStore(ModuleStoreBase):
to specified depth
to specified depth
"""
"""
data_cache
=
self
.
_cache_children
(
items
,
depth
)
data_cache
=
self
.
_cache_children
(
items
,
depth
)
inheritance_cache
=
self
.
_cache_metadata_inheritance
(
items
,
depth
)
# if we are loading a course object, if we're not prefetching children (depth != 0) then don't
# if we are loading a course object, if we're not prefetching children (depth != 0) then don't
# bother with the metadata inheritence
# bother with the metadata inheritance
return
[
self
.
_load_item
(
item
,
data_cache
,
inheritance_cache
)
for
item
in
items
]
return
[
self
.
_load_item
(
item
,
data_cache
,
apply_cached_metadata
=
(
item
[
'location'
][
'category'
]
!=
'course'
or
depth
!=
0
))
for
item
in
items
]
def
get_courses
(
self
):
def
get_courses
(
self
):
'''
'''
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
View file @
b609a969
...
@@ -103,58 +103,3 @@ class TestMongoModuleStore(object):
...
@@ -103,58 +103,3 @@ class TestMongoModuleStore(object):
def
test_path_to_location
(
self
):
def
test_path_to_location
(
self
):
'''Make sure that path_to_location works'''
'''Make sure that path_to_location works'''
check_path_to_location
(
self
.
store
)
check_path_to_location
(
self
.
store
)
def
test_metadata_inheritance_query_count
(
self
):
'''
When retrieving items from mongo, we should only query the cache a number of times
equal to the number of courses being retrieved from.
We should also not query
'''
self
.
store
.
metadata_inheritance_cache
=
Mock
()
get_many
=
self
.
store
.
metadata_inheritance_cache
.
get_many
set_many
=
self
.
store
.
metadata_inheritance_cache
.
set_many
get_many
.
return_value
=
{(
'edX'
,
'toy'
):
{}}
self
.
store
.
get_item
(
Location
(
"i4x://edX/toy/course/2012_Fall"
),
depth
=
0
)
assert_false
(
get_many
.
called
)
assert_false
(
set_many
.
called
)
get_many
.
reset_mock
()
self
.
store
.
get_item
(
Location
(
"i4x://edX/toy/course/2012_Fall"
),
depth
=
3
)
get_many
.
assert_called_with
([(
'edX'
,
'toy'
)])
assert_equals
(
0
,
set_many
.
call_count
)
get_many
.
reset_mock
()
self
.
store
.
get_items
(
Location
(
'i4x'
,
'edX'
,
None
,
'course'
,
None
),
depth
=
0
)
assert_false
(
get_many
.
called
)
assert_false
(
set_many
.
called
)
get_many
.
reset_mock
()
self
.
store
.
get_items
(
Location
(
'i4x'
,
'edX'
,
None
,
'course'
,
None
),
depth
=
3
)
assert_equals
(
1
,
get_many
.
call_count
)
assert_equals
([(
'edX'
,
'simple'
),
(
'edX'
,
'toy'
)],
sorted
(
get_many
.
call_args
[
0
][
0
]))
assert_equals
(
1
,
set_many
.
call_count
)
assert_equals
([(
'edX'
,
'simple'
)],
sorted
(
set_many
.
call_args
[
0
][
0
]
.
keys
()))
get_many
.
reset_mock
()
self
.
store
.
get_items
(
Location
(
'i4x'
,
'edX'
,
None
,
None
,
None
),
depth
=
0
)
assert_equals
(
1
,
get_many
.
call_count
)
assert_equals
([(
'edX'
,
'simple'
),
(
'edX'
,
'toy'
)],
sorted
(
get_many
.
call_args
[
0
][
0
]))
assert_equals
(
1
,
set_many
.
call_count
)
assert_equals
([(
'edX'
,
'simple'
)],
sorted
(
set_many
.
call_args
[
0
][
0
]
.
keys
()))
get_many
.
reset_mock
()
def
test_metadata_inheritance_query_count_forced_refresh
(
self
):
self
.
store
.
metadata_inheritance_cache
=
Mock
()
get_many
=
self
.
store
.
metadata_inheritance_cache
.
get_many
set_many
=
self
.
store
.
metadata_inheritance_cache
.
set_many
get_many
.
return_value
=
{(
'edX'
,
'toy'
):
{}}
self
.
store
.
get_cached_metadata_inheritance_trees
(
[
Location
(
"i4x://edX/toy/course/2012_Fall"
),
Location
(
"i4x://edX/simple/course/2012_Fall"
)],
True
)
assert_false
(
get_many
.
called
)
assert_equals
(
1
,
set_many
.
call_count
)
assert_equals
([(
'edX'
,
'simple'
),
(
'edX'
,
'toy'
)],
sorted
(
set_many
.
call_args
[
0
][
0
]
.
keys
()))
lms/envs/common.py
View file @
b609a969
...
@@ -364,6 +364,7 @@ TEMPLATE_LOADERS = (
...
@@ -364,6 +364,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES
=
(
MIDDLEWARE_CLASSES
=
(
'contentserver.middleware.StaticContentServer'
,
'contentserver.middleware.StaticContentServer'
,
'request_cache.middleware.RequestCache'
,
'django_comment_client.middleware.AjaxExceptionMiddleware'
,
'django_comment_client.middleware.AjaxExceptionMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
...
...
lms/one_time_startup.py
View file @
b609a969
...
@@ -2,13 +2,15 @@ import logging
...
@@ -2,13 +2,15 @@ import logging
from
dogapi
import
dog_http_api
,
dog_stats_api
from
dogapi
import
dog_http_api
,
dog_stats_api
from
django.conf
import
settings
from
django.conf
import
settings
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
request_cache.middleware
import
RequestCache
from
django.core.cache
import
get_cache
,
InvalidCacheBackendError
from
django.core.cache
import
get_cache
,
InvalidCacheBackendError
cache
=
get_cache
(
'mongo_metadata_inheritance'
)
cache
=
get_cache
(
'mongo_metadata_inheritance'
)
for
store_name
in
settings
.
MODULESTORE
:
for
store_name
in
settings
.
MODULESTORE
:
store
=
modulestore
(
store_name
)
store
=
modulestore
(
store_name
)
store
.
metadata_inheritance_cache
=
cache
store
.
metadata_inheritance_cache_subsystem
=
cache
store
.
request_cache
=
RequestCache
.
get_request_cache
()
if
hasattr
(
settings
,
'DATADOG_API'
):
if
hasattr
(
settings
,
'DATADOG_API'
):
dog_http_api
.
api_key
=
settings
.
DATADOG_API
dog_http_api
.
api_key
=
settings
.
DATADOG_API
...
...
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