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
e83182c7
Commit
e83182c7
authored
Mar 17, 2017
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Have generate_course_blocks pass with_storage option to celery tasks
parent
a2daa8d0
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
129 additions
and
67 deletions
+129
-67
cms/celery.py
+1
-0
cms/djangoapps/contentstore/tests/test_import.py
+1
-1
openedx/core/djangoapps/content/block_structure/config/__init__.py
+19
-1
openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py
+13
-22
openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py
+9
-6
openedx/core/djangoapps/content/block_structure/signals.py
+5
-5
openedx/core/djangoapps/content/block_structure/tasks.py
+75
-26
openedx/core/djangoapps/content/block_structure/tests/test_signals.py
+3
-3
openedx/core/djangoapps/content/block_structure/tests/test_tasks.py
+3
-3
No files found.
cms/celery.py
View file @
e83182c7
...
@@ -33,4 +33,5 @@ class Router(AlternateEnvironmentRouter):
...
@@ -33,4 +33,5 @@ class Router(AlternateEnvironmentRouter):
"""
"""
return
{
return
{
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache'
:
'lms'
,
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache'
:
'lms'
,
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache_v2'
:
'lms'
,
}
}
cms/djangoapps/contentstore/tests/test_import.py
View file @
e83182c7
...
@@ -41,7 +41,7 @@ class ContentStoreImportTest(SignalDisconnectTestMixin, ModuleStoreTestCase):
...
@@ -41,7 +41,7 @@ class ContentStoreImportTest(SignalDisconnectTestMixin, ModuleStoreTestCase):
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
self
.
user_password
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
self
.
user_password
)
# block_structure.update_course_in_cache cannot succeed in tests, as it needs to be run async on an lms worker
# block_structure.update_course_in_cache cannot succeed in tests, as it needs to be run async on an lms worker
self
.
task_patcher
=
patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache'
)
self
.
task_patcher
=
patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache
_v2
'
)
self
.
_mock_lms_task
=
self
.
task_patcher
.
start
()
self
.
_mock_lms_task
=
self
.
task_patcher
.
start
()
def
tearDown
(
self
):
def
tearDown
(
self
):
...
...
openedx/core/djangoapps/content/block_structure/config/__init__.py
View file @
e83182c7
...
@@ -2,12 +2,17 @@
...
@@ -2,12 +2,17 @@
This module contains various configuration settings via
This module contains various configuration settings via
waffle switches for the Block Structure framework.
waffle switches for the Block Structure framework.
"""
"""
import
logging
from
openedx.core.djangolib.waffle_utils
import
is_switch_enabled
from
openedx.core.djangolib.waffle_utils
import
is_switch_enabled
from
request_cache.middleware
import
request_cached
from
request_cache.middleware
import
request_cached
,
RequestCache
,
func_call_cache_key
from
.models
import
BlockStructureConfiguration
from
.models
import
BlockStructureConfiguration
log
=
logging
.
getLogger
(
__name__
)
INVALIDATE_CACHE_ON_PUBLISH
=
u'invalidate_cache_on_publish'
INVALIDATE_CACHE_ON_PUBLISH
=
u'invalidate_cache_on_publish'
STORAGE_BACKING_FOR_CACHE
=
u'storage_backing_for_cache'
STORAGE_BACKING_FOR_CACHE
=
u'storage_backing_for_cache'
RAISE_ERROR_WHEN_NOT_FOUND
=
u'raise_error_when_not_found'
RAISE_ERROR_WHEN_NOT_FOUND
=
u'raise_error_when_not_found'
...
@@ -23,6 +28,19 @@ def is_enabled(setting_name):
...
@@ -23,6 +28,19 @@ def is_enabled(setting_name):
return
is_switch_enabled
(
bs_waffle_name
)
return
is_switch_enabled
(
bs_waffle_name
)
def
enable_for_current_request
(
setting_name
):
"""
Enables the given block_structure setting for the
duration of the current request.
"""
cache_key
=
func_call_cache_key
(
is_switch_enabled
.
request_cached_contained_func
,
_bs_waffle_switch_name
(
setting_name
),
)
RequestCache
.
get_request_cache
()
.
data
[
cache_key
]
=
True
log
.
warning
(
u'BlockStructure: Config
%
s is enabled for current request.'
,
setting_name
)
@request_cached
@request_cached
def
num_versions_to_keep
():
def
num_versions_to_keep
():
"""
"""
...
...
openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py
View file @
e83182c7
...
@@ -7,7 +7,7 @@ from django.core.management.base import BaseCommand
...
@@ -7,7 +7,7 @@ from django.core.management.base import BaseCommand
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
import
openedx.core.djangoapps.content.block_structure.api
as
api
import
openedx.core.djangoapps.content.block_structure.api
as
api
from
openedx.core.djangoapps.content.block_structure.config
import
_bs_waffle_switch_name
,
STORAGE_BACKING_FOR_CACHE
from
openedx.core.djangoapps.content.block_structure.config
import
STORAGE_BACKING_FOR_CACHE
,
enable_for_current_request
import
openedx.core.djangoapps.content.block_structure.tasks
as
tasks
import
openedx.core.djangoapps.content.block_structure.tasks
as
tasks
import
openedx.core.djangoapps.content.block_structure.store
as
store
import
openedx.core.djangoapps.content.block_structure.store
as
store
from
openedx.core.lib.command_utils
import
(
from
openedx.core.lib.command_utils
import
(
...
@@ -15,8 +15,6 @@ from openedx.core.lib.command_utils import (
...
@@ -15,8 +15,6 @@ from openedx.core.lib.command_utils import (
validate_dependent_option
,
validate_dependent_option
,
parse_course_keys
,
parse_course_keys
,
)
)
from
request_cache.middleware
import
RequestCache
,
func_call_cache_key
from
openedx.core.djangolib.waffle_utils
import
is_switch_enabled
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -100,9 +98,9 @@ class Command(BaseCommand):
...
@@ -100,9 +98,9 @@ class Command(BaseCommand):
self
.
_set_log_levels
(
options
)
self
.
_set_log_levels
(
options
)
log
.
critical
(
u'STARTED generating Course Blocks for
%
d courses.'
,
len
(
course_keys
))
log
.
critical
(
u'
BlockStructure:
STARTED generating Course Blocks for
%
d courses.'
,
len
(
course_keys
))
self
.
_generate_course_blocks
(
options
,
course_keys
)
self
.
_generate_course_blocks
(
options
,
course_keys
)
log
.
critical
(
u'FINISHED generating Course Blocks for
%
d courses.'
,
len
(
course_keys
))
log
.
critical
(
u'
BlockStructure:
FINISHED generating Course Blocks for
%
d courses.'
,
len
(
course_keys
))
def
_set_log_levels
(
self
,
options
):
def
_set_log_levels
(
self
,
options
):
"""
"""
...
@@ -129,16 +127,14 @@ class Command(BaseCommand):
...
@@ -129,16 +127,14 @@ class Command(BaseCommand):
Generates course blocks for the given course_keys per the given options.
Generates course blocks for the given course_keys per the given options.
"""
"""
if
options
.
get
(
'with_storage'
):
if
options
.
get
(
'with_storage'
):
self
.
_enable_storage
(
)
enable_for_current_request
(
STORAGE_BACKING_FOR_CACHE
)
for
course_key
in
course_keys
:
for
course_key
in
course_keys
:
try
:
try
:
log
.
info
(
u'STARTED generating Course Blocks for course:
%
s.'
,
course_key
)
self
.
_generate_for_course
(
options
,
course_key
)
self
.
_generate_for_course
(
options
,
course_key
)
log
.
info
(
u'FINISHED generating Course Blocks for course:
%
s.'
,
course_key
)
except
Exception
as
ex
:
# pylint: disable=broad-except
except
Exception
as
ex
:
# pylint: disable=broad-except
log
.
exception
(
log
.
exception
(
u'An error occurred while generating course blocks for
%
s:
%
s'
,
u'
BlockStructure:
An error occurred while generating course blocks for
%
s:
%
s'
,
unicode
(
course_key
),
unicode
(
course_key
),
ex
.
message
,
ex
.
message
,
)
)
...
@@ -148,20 +144,15 @@ class Command(BaseCommand):
...
@@ -148,20 +144,15 @@ class Command(BaseCommand):
Generates course blocks for the given course_key per the given options.
Generates course blocks for the given course_key per the given options.
"""
"""
if
options
.
get
(
'enqueue_task'
):
if
options
.
get
(
'enqueue_task'
):
action
=
tasks
.
update_course_in_cache
if
options
.
get
(
'force_update'
)
else
tasks
.
get_course_in_cache
action
=
tasks
.
update_course_in_cache
_v2
if
options
.
get
(
'force_update'
)
else
tasks
.
get_course_in_cache_v2
task_options
=
{
'routing_key'
:
options
[
'routing_key'
]}
if
options
.
get
(
'routing_key'
)
else
{}
task_options
=
{
'routing_key'
:
options
[
'routing_key'
]}
if
options
.
get
(
'routing_key'
)
else
{}
action
.
apply_async
([
unicode
(
course_key
)],
**
task_options
)
result
=
action
.
apply_async
(
kwargs
=
dict
(
course_id
=
unicode
(
course_key
),
with_storage
=
options
.
get
(
'with_storage'
)),
**
task_options
)
log
.
info
(
u'BlockStructure: ENQUEUED generating for course:
%
s, task_id:
%
s.'
,
course_key
,
result
.
id
)
else
:
else
:
log
.
info
(
u'BlockStructure: STARTED generating for course:
%
s.'
,
course_key
)
action
=
api
.
update_course_in_cache
if
options
.
get
(
'force_update'
)
else
api
.
get_course_in_cache
action
=
api
.
update_course_in_cache
if
options
.
get
(
'force_update'
)
else
api
.
get_course_in_cache
action
(
course_key
)
action
(
course_key
)
log
.
info
(
u'BlockStructure: FINISHED generating for course:
%
s.'
,
course_key
)
def
_enable_storage
(
self
):
"""
Enables storage backing by setting the waffle's cached value to True.
"""
cache_key
=
func_call_cache_key
(
is_switch_enabled
.
request_cached_contained_func
,
_bs_waffle_switch_name
(
STORAGE_BACKING_FOR_CACHE
),
)
RequestCache
.
get_request_cache
()
.
data
[
cache_key
]
=
True
log
.
warning
(
u'STORAGE_BACKING_FOR_CACHE is enabled.'
)
openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py
View file @
e83182c7
...
@@ -107,20 +107,20 @@ class TestGenerateCourseBlocks(ModuleStoreTestCase):
...
@@ -107,20 +107,20 @@ class TestGenerateCourseBlocks(ModuleStoreTestCase):
command_options
[
'routing_key'
]
=
routing_key
command_options
[
'routing_key'
]
=
routing_key
with
patch
(
with
patch
(
'
lms.djangoapps.course_blocks
.management.commands.generate_course_blocks.tasks'
'
openedx.core.djangoapps.content.block_structure
.management.commands.generate_course_blocks.tasks'
)
as
mock_tasks
:
)
as
mock_tasks
:
with
patch
(
with
patch
(
'
lms.djangoapps.course_blocks
.management.commands.generate_course_blocks.api'
'
openedx.core.djangoapps.content.block_structure
.management.commands.generate_course_blocks.api'
)
as
mock_api
:
)
as
mock_api
:
self
.
command
.
handle
(
**
command_options
)
self
.
command
.
handle
(
**
command_options
)
self
.
assertEqual
(
self
.
assertEqual
(
mock_tasks
.
update_course_in_cache
.
apply_async
.
call_count
,
mock_tasks
.
update_course_in_cache
_v2
.
apply_async
.
call_count
,
self
.
num_courses
if
enqueue_task
and
force_update
else
0
,
self
.
num_courses
if
enqueue_task
and
force_update
else
0
,
)
)
self
.
assertEqual
(
self
.
assertEqual
(
mock_tasks
.
get_course_in_cache
.
apply_async
.
call_count
,
mock_tasks
.
get_course_in_cache
_v2
.
apply_async
.
call_count
,
self
.
num_courses
if
enqueue_task
and
not
force_update
else
0
,
self
.
num_courses
if
enqueue_task
and
not
force_update
else
0
,
)
)
...
@@ -134,14 +134,17 @@ class TestGenerateCourseBlocks(ModuleStoreTestCase):
...
@@ -134,14 +134,17 @@ class TestGenerateCourseBlocks(ModuleStoreTestCase):
)
)
if
enqueue_task
:
if
enqueue_task
:
task_action
=
mock_tasks
.
update_course_in_cache
if
force_update
else
mock_tasks
.
get_course_in_cache
if
force_update
:
task_action
=
mock_tasks
.
update_course_in_cache_v2
else
:
task_action
=
mock_tasks
.
get_course_in_cache_v2
task_options
=
task_action
.
apply_async
.
call_args
[
1
]
task_options
=
task_action
.
apply_async
.
call_args
[
1
]
if
routing_key
:
if
routing_key
:
self
.
assertEquals
(
task_options
[
'routing_key'
],
routing_key
)
self
.
assertEquals
(
task_options
[
'routing_key'
],
routing_key
)
else
:
else
:
self
.
assertNotIn
(
'routing_key'
,
task_options
)
self
.
assertNotIn
(
'routing_key'
,
task_options
)
@patch
(
'
lms.djangoapps.course_blocks
.management.commands.generate_course_blocks.log'
)
@patch
(
'
openedx.core.djangoapps.content.block_structure
.management.commands.generate_course_blocks.log'
)
def
test_not_found_key
(
self
,
mock_log
):
def
test_not_found_key
(
self
,
mock_log
):
self
.
command
.
handle
(
courses
=
[
'fake/course/id'
])
self
.
command
.
handle
(
courses
=
[
'fake/course/id'
])
self
.
assertTrue
(
mock_log
.
exception
.
called
)
self
.
assertTrue
(
mock_log
.
exception
.
called
)
...
...
openedx/core/djangoapps/content/block_structure/signals.py
View file @
e83182c7
...
@@ -10,11 +10,11 @@ from opaque_keys.edx.locator import LibraryLocator
...
@@ -10,11 +10,11 @@ from opaque_keys.edx.locator import LibraryLocator
from
.
import
config
from
.
import
config
from
.api
import
clear_course_from_cache
from
.api
import
clear_course_from_cache
from
.tasks
import
update_course_in_cache
from
.tasks
import
update_course_in_cache
_v2
@receiver
(
SignalHandler
.
course_published
)
@receiver
(
SignalHandler
.
course_published
)
def
_
listen_for
_course_publish
(
sender
,
course_key
,
**
kwargs
):
# pylint: disable=unused-argument
def
_
update_block_structure_on
_course_publish
(
sender
,
course_key
,
**
kwargs
):
# pylint: disable=unused-argument
"""
"""
Catches the signal that a course has been published in the module
Catches the signal that a course has been published in the module
store and creates/updates the corresponding cache entry.
store and creates/updates the corresponding cache entry.
...
@@ -26,14 +26,14 @@ def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable
...
@@ -26,14 +26,14 @@ def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable
if
config
.
is_enabled
(
config
.
INVALIDATE_CACHE_ON_PUBLISH
):
if
config
.
is_enabled
(
config
.
INVALIDATE_CACHE_ON_PUBLISH
):
clear_course_from_cache
(
course_key
)
clear_course_from_cache
(
course_key
)
update_course_in_cache
.
apply_async
(
update_course_in_cache
_v2
.
apply_async
(
[
unicode
(
course_key
)]
,
kwargs
=
dict
(
course_id
=
unicode
(
course_key
))
,
countdown
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'COURSE_PUBLISH_TASK_DELAY'
],
countdown
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'COURSE_PUBLISH_TASK_DELAY'
],
)
)
@receiver
(
SignalHandler
.
course_deleted
)
@receiver
(
SignalHandler
.
course_deleted
)
def
_
listen_for
_course_delete
(
sender
,
course_key
,
**
kwargs
):
# pylint: disable=unused-argument
def
_
delete_block_structure_on
_course_delete
(
sender
,
course_key
,
**
kwargs
):
# pylint: disable=unused-argument
"""
"""
Catches the signal that a course has been deleted from the
Catches the signal that a course has been deleted from the
module store and invalidates the corresponding cache entry if one
module store and invalidates the corresponding cache entry if one
...
...
openedx/core/djangoapps/content/block_structure/tasks.py
View file @
e83182c7
...
@@ -13,6 +13,7 @@ from opaque_keys.edx.keys import CourseKey
...
@@ -13,6 +13,7 @@ from opaque_keys.edx.keys import CourseKey
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
openedx.core.djangoapps.content.block_structure
import
api
from
openedx.core.djangoapps.content.block_structure
import
api
from
openedx.core.djangoapps.content.block_structure.config
import
STORAGE_BACKING_FOR_CACHE
,
enable_for_current_request
log
=
logging
.
getLogger
(
'edx.celery.task'
)
log
=
logging
.
getLogger
(
'edx.celery.task'
)
...
@@ -21,53 +22,101 @@ RETRY_TASKS = (ItemNotFoundError, TypeError, ValInternalError)
...
@@ -21,53 +22,101 @@ RETRY_TASKS = (ItemNotFoundError, TypeError, ValInternalError)
NO_RETRY_TASKS
=
(
XMLSyntaxError
,
LoncapaProblemError
,
UnicodeEncodeError
)
NO_RETRY_TASKS
=
(
XMLSyntaxError
,
LoncapaProblemError
,
UnicodeEncodeError
)
@task
(
def
block_structure_task
(
**
kwargs
):
default_retry_delay
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_DEFAULT_RETRY_DELAY'
],
"""
max_retries
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_MAX_RETRIES'
],
Decorator for block structure tasks.
bind
=
True
,
"""
)
return
task
(
default_retry_delay
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_DEFAULT_RETRY_DELAY'
],
max_retries
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_MAX_RETRIES'
],
bind
=
True
,
**
kwargs
)
@block_structure_task
()
def
update_course_in_cache_v2
(
self
,
**
kwargs
):
"""
Updates the course blocks (mongo -> BlockStructure) for the specified course.
Keyword Arguments:
course_id (string) - The string serialized value of the course key.
with_storage (boolean) - Whether or not storage backing should be
enabled for the generated block structure(s).
"""
_update_course_in_cache
(
self
,
**
kwargs
)
@block_structure_task
()
def
update_course_in_cache
(
self
,
course_id
):
def
update_course_in_cache
(
self
,
course_id
):
"""
"""
Updates the course blocks (in the database) for the specified course.
Updates the course blocks (mongo -> BlockStructure) for the specified course.
"""
_update_course_in_cache
(
self
,
course_id
=
course_id
)
def
_update_course_in_cache
(
self
,
**
kwargs
):
"""
Updates the course blocks (mongo -> BlockStructure) for the specified course.
"""
if
kwargs
.
get
(
'with_storage'
):
enable_for_current_request
(
STORAGE_BACKING_FOR_CACHE
)
_call_and_retry_if_needed
(
self
,
api
.
update_course_in_cache
,
**
kwargs
)
@block_structure_task
()
def
get_course_in_cache_v2
(
self
,
**
kwargs
):
"""
Gets the course blocks for the specified course, updating the cache if needed.
Keyword Arguments:
course_id (string) - The string serialized value of the course key.
with_storage (boolean) - Whether or not storage backing should be
enabled for any generated block structure(s).
"""
"""
_
call_and_retry_if_needed
(
course_id
,
api
.
update_course_in_cache
,
update_course_in_cache
,
self
.
request
.
id
)
_
get_course_in_cache
(
self
,
**
kwargs
)
@task
(
@block_structure_task
()
default_retry_delay
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_DEFAULT_RETRY_DELAY'
],
max_retries
=
settings
.
BLOCK_STRUCTURES_SETTINGS
[
'TASK_MAX_RETRIES'
],
bind
=
True
,
)
def
get_course_in_cache
(
self
,
course_id
):
def
get_course_in_cache
(
self
,
course_id
):
"""
"""
Gets the course blocks for the specified course, updating the cache if needed.
Gets the course blocks for the specified course, updating the cache if needed.
"""
"""
_call_and_retry_if_needed
(
course_id
,
api
.
get_course_in_cache
,
get_course_in_cache
,
self
.
request
.
id
)
_get_course_in_cache
(
self
,
course_id
=
course_id
)
def
_get_course_in_cache
(
self
,
**
kwargs
):
"""
Gets the course blocks for the specified course, updating the cache if needed.
"""
if
kwargs
.
get
(
'with_storage'
):
enable_for_current_request
(
STORAGE_BACKING_FOR_CACHE
)
_call_and_retry_if_needed
(
self
,
api
.
get_course_in_cache
,
**
kwargs
)
def
_call_and_retry_if_needed
(
course_id
,
api_method
,
task_method
,
task_id
):
def
_call_and_retry_if_needed
(
self
,
api_method
,
**
kwargs
):
"""
"""
Calls the given api_method with the given course_id, retrying task_method upon failure.
Calls the given api_method with the given course_id, retrying task_method upon failure.
"""
"""
try
:
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
kwargs
[
'course_id'
]
)
api_method
(
course_key
)
api_method
(
course_key
)
except
NO_RETRY_TASKS
as
exc
:
except
NO_RETRY_TASKS
:
# Known unrecoverable errors
# Known unrecoverable errors
log
.
exception
(
log
.
exception
(
"
update_course_in_cache encountered unrecoverable error in course {}, task_id {}"
.
format
(
"
BlockStructure:
%
s encountered unrecoverable error in course
%
s, task_id
%
s"
,
course_id
,
self
.
__name__
,
task_id
kwargs
.
get
(
'course_id'
),
)
self
.
request
.
id
,
)
)
raise
raise
except
RETRY_TASKS
as
exc
:
except
RETRY_TASKS
as
exc
:
log
.
exception
(
"
%
s encountered expected error, retrying."
,
task_method
.
__name__
)
log
.
exception
(
"
%
s encountered expected error, retrying."
,
self
.
__name__
)
raise
task_method
.
retry
(
args
=
[
course_id
]
,
exc
=
exc
)
raise
self
.
retry
(
kwargs
=
kwargs
,
exc
=
exc
)
except
Exception
as
exc
:
# pylint: disable=broad-except
except
Exception
as
exc
:
# pylint: disable=broad-except
log
.
exception
(
log
.
exception
(
"
%
s encountered unknown error. Retry #
%
d"
,
"BlockStructure:
%
s encountered unknown error in course
%
s, task_id
%
s. Retry #
%
d"
,
task_method
.
__name__
,
self
.
__name__
,
task_method
.
request
.
retries
,
kwargs
.
get
(
'course_id'
),
self
.
request
.
id
,
self
.
request
.
retries
,
)
)
raise
task_method
.
retry
(
args
=
[
course_id
]
,
exc
=
exc
)
raise
self
.
retry
(
kwargs
=
kwargs
,
exc
=
exc
)
openedx/core/djangoapps/content/block_structure/tests/test_signals.py
View file @
e83182c7
...
@@ -11,7 +11,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
...
@@ -11,7 +11,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
from
..api
import
get_block_structure_manager
from
..api
import
get_block_structure_manager
from
..config
import
INVALIDATE_CACHE_ON_PUBLISH
from
..config
import
INVALIDATE_CACHE_ON_PUBLISH
from
..signals
import
_
listen_for
_course_publish
from
..signals
import
_
update_block_structure_on
_course_publish
from
.helpers
import
is_course_in_block_structure_cache
,
override_config_setting
from
.helpers
import
is_course_in_block_structure_cache
,
override_config_setting
...
@@ -76,7 +76,7 @@ class CourseBlocksSignalTest(ModuleStoreTestCase):
...
@@ -76,7 +76,7 @@ class CourseBlocksSignalTest(ModuleStoreTestCase):
(
LibraryLocator
(
org
=
'org'
,
course
=
'course'
),
False
),
(
LibraryLocator
(
org
=
'org'
,
course
=
'course'
),
False
),
)
)
@ddt.unpack
@ddt.unpack
@patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache.apply_async'
)
@patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache
_v2
.apply_async'
)
def
test_update_only_for_courses
(
self
,
key
,
expect_update_called
,
mock_update
):
def
test_update_only_for_courses
(
self
,
key
,
expect_update_called
,
mock_update
):
_
listen_for
_course_publish
(
sender
=
None
,
course_key
=
key
)
_
update_block_structure_on
_course_publish
(
sender
=
None
,
course_key
=
key
)
self
.
assertEqual
(
mock_update
.
called
,
expect_update_called
)
self
.
assertEqual
(
mock_update
.
called
,
expect_update_called
)
openedx/core/djangoapps/content/block_structure/tests/test_tasks.py
View file @
e83182c7
...
@@ -6,19 +6,19 @@ from mock import patch
...
@@ -6,19 +6,19 @@ from mock import patch
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
..tasks
import
update_course_in_cache
from
..tasks
import
update_course_in_cache
_v2
class
UpdateCourseInCacheTaskTest
(
ModuleStoreTestCase
):
class
UpdateCourseInCacheTaskTest
(
ModuleStoreTestCase
):
"""
"""
Ensures that the update_course_in_cache task runs as expected.
Ensures that the update_course_in_cache task runs as expected.
"""
"""
@patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache.retry'
)
@patch
(
'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache
_v2
.retry'
)
@patch
(
'openedx.core.djangoapps.content.block_structure.api.update_course_in_cache'
)
@patch
(
'openedx.core.djangoapps.content.block_structure.api.update_course_in_cache'
)
def
test_retry_on_error
(
self
,
mock_update
,
mock_retry
):
def
test_retry_on_error
(
self
,
mock_update
,
mock_retry
):
"""
"""
Ensures that tasks will be retried if IntegrityErrors are encountered.
Ensures that tasks will be retried if IntegrityErrors are encountered.
"""
"""
mock_update
.
side_effect
=
Exception
(
"WHAMMY"
)
mock_update
.
side_effect
=
Exception
(
"WHAMMY"
)
update_course_in_cache
.
apply
(
args
=
[
"invalid_course_key raises exception 12345 meow"
]
)
update_course_in_cache
_v2
.
apply
(
kwargs
=
dict
(
course_id
=
"invalid_course_key raises exception 12345 meow"
)
)
self
.
assertTrue
(
mock_retry
.
called
)
self
.
assertTrue
(
mock_retry
.
called
)
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