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
a0dcc97e
Commit
a0dcc97e
authored
Jun 12, 2013
by
Brian Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tasks now extract task_input and course_id from InstructorTask, instead of passing explicitly.
parent
a67674fe
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
57 additions
and
47 deletions
+57
-47
lms/djangoapps/instructor_task/api_helper.py
+1
-1
lms/djangoapps/instructor_task/tasks.py
+20
-26
lms/djangoapps/instructor_task/tasks_helper.py
+26
-11
lms/djangoapps/instructor_task/tests/test_api.py
+8
-7
lms/djangoapps/instructor_task/tests/test_integration.py
+2
-2
No files found.
lms/djangoapps/instructor_task/api_helper.py
View file @
a0dcc97e
...
@@ -277,7 +277,7 @@ def submit_task(request, task_type, task_class, course_id, task_input, task_key)
...
@@ -277,7 +277,7 @@ def submit_task(request, task_type, task_class, course_id, task_input, task_key)
# submit task:
# submit task:
task_id
=
instructor_task
.
task_id
task_id
=
instructor_task
.
task_id
task_args
=
[
instructor_task
.
id
,
course_id
,
task_input
,
_get_xmodule_instance_args
(
request
)]
task_args
=
[
instructor_task
.
id
,
_get_xmodule_instance_args
(
request
)]
task_class
.
apply_async
(
task_args
,
task_id
=
task_id
)
task_class
.
apply_async
(
task_args
,
task_id
=
task_id
)
return
instructor_task
return
instructor_task
lms/djangoapps/instructor_task/tasks.py
View file @
a0dcc97e
"""
"""
This file contains tasks that are designed to perform background operations on the
This file contains tasks that are designed to perform background operations on the
running state of a course.
running state of a course.
"""
"""
from
celery
import
task
from
celery
import
task
from
instructor_task.tasks_helper
import
(
_
update_problem_module_state
,
from
instructor_task.tasks_helper
import
(
update_problem_module_state
,
_
rescore_problem_module_state
,
rescore_problem_module_state
,
_reset_problem
_attempts_module_state
,
reset
_attempts_module_state
,
_
delete_problem_module_state
)
delete_problem_module_state
)
@task
@task
def
rescore_problem
(
entry_id
,
course_id
,
task_input
,
xmodule_instance_args
):
def
rescore_problem
(
entry_id
,
xmodule_instance_args
):
"""Rescores problem in `course_id`.
"""Rescores problem in `course_id`.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
...
@@ -29,19 +29,15 @@ def rescore_problem(entry_id, course_id, task_input, xmodule_instance_args):
...
@@ -29,19 +29,15 @@ def rescore_problem(entry_id, course_id, task_input, xmodule_instance_args):
to instantiate an xmodule instance.
to instantiate an xmodule instance.
"""
"""
action_name
=
'rescored'
action_name
=
'rescored'
update_fcn
=
_
rescore_problem_module_state
update_fcn
=
rescore_problem_module_state
filter_fcn
=
lambda
(
modules_to_update
):
modules_to_update
.
filter
(
state__contains
=
'"done": true'
)
filter_fcn
=
lambda
(
modules_to_update
):
modules_to_update
.
filter
(
state__contains
=
'"done": true'
)
problem_url
=
task_input
.
get
(
'problem_url'
)
return
update_problem_module_state
(
entry_id
,
student_ident
=
None
update_fcn
,
action_name
,
filter_fcn
=
filter_fcn
,
if
'student'
in
task_input
:
xmodule_instance_args
=
xmodule_instance_args
)
student_ident
=
task_input
[
'student'
]
return
_update_problem_module_state
(
entry_id
,
course_id
,
problem_url
,
student_ident
,
update_fcn
,
action_name
,
filter_fcn
=
filter_fcn
,
xmodule_instance_args
=
xmodule_instance_args
)
@task
@task
def
reset_problem_attempts
(
entry_id
,
course_id
,
task_input
,
xmodule_instance_args
):
def
reset_problem_attempts
(
entry_id
,
xmodule_instance_args
):
"""Resets problem attempts to zero for `problem_url` in `course_id` for all students.
"""Resets problem attempts to zero for `problem_url` in `course_id` for all students.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
...
@@ -54,15 +50,14 @@ def reset_problem_attempts(entry_id, course_id, task_input, xmodule_instance_arg
...
@@ -54,15 +50,14 @@ def reset_problem_attempts(entry_id, course_id, task_input, xmodule_instance_arg
to instantiate an xmodule instance.
to instantiate an xmodule instance.
"""
"""
action_name
=
'reset'
action_name
=
'reset'
update_fcn
=
_reset_problem_attempts_module_state
update_fcn
=
reset_attempts_module_state
problem_url
=
task_input
.
get
(
'problem_url'
)
return
update_problem_module_state
(
entry_id
,
return
_update_problem_module_state
(
entry_id
,
course_id
,
problem_url
,
None
,
update_fcn
,
action_name
,
filter_fcn
=
None
,
update_fcn
,
action_name
,
filter_fcn
=
None
,
xmodule_instance_args
=
xmodule_instance_args
)
xmodule_instance_args
=
xmodule_instance_args
)
@task
@task
def
delete_problem_state
(
entry_id
,
course_id
,
task_input
,
xmodule_instance_args
):
def
delete_problem_state
(
entry_id
,
xmodule_instance_args
):
"""Deletes problem state entirely for `problem_url` in `course_id` for all students.
"""Deletes problem state entirely for `problem_url` in `course_id` for all students.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
`entry_id` is the id value of the InstructorTask entry that corresponds to this task.
...
@@ -75,8 +70,7 @@ def delete_problem_state(entry_id, course_id, task_input, xmodule_instance_args)
...
@@ -75,8 +70,7 @@ def delete_problem_state(entry_id, course_id, task_input, xmodule_instance_args)
to instantiate an xmodule instance.
to instantiate an xmodule instance.
"""
"""
action_name
=
'deleted'
action_name
=
'deleted'
update_fcn
=
_delete_problem_module_state
update_fcn
=
delete_problem_module_state
problem_url
=
task_input
.
get
(
'problem_url'
)
return
update_problem_module_state
(
entry_id
,
return
_update_problem_module_state
(
entry_id
,
course_id
,
problem_url
,
None
,
update_fcn
,
action_name
,
filter_fcn
=
None
,
update_fcn
,
action_name
,
filter_fcn
=
None
,
xmodule_instance_args
=
xmodule_instance_args
)
xmodule_instance_args
=
xmodule_instance_args
)
lms/djangoapps/instructor_task/tasks_helper.py
View file @
a0dcc97e
"""
"""
This file contains tasks that are designed to perform background operations on the
This file contains tasks that are designed to perform background operations on the
running state of a course.
running state of a course.
...
@@ -50,7 +50,7 @@ class UpdateProblemModuleStateError(Exception):
...
@@ -50,7 +50,7 @@ class UpdateProblemModuleStateError(Exception):
def
_perform_module_state_update
(
course_id
,
module_state_key
,
student_identifier
,
update_fcn
,
action_name
,
filter_fcn
,
def
_perform_module_state_update
(
course_id
,
module_state_key
,
student_identifier
,
update_fcn
,
action_name
,
filter_fcn
,
xmodule_instance_args
):
xmodule_instance_args
):
"""
"""
Performs generic update by visiting StudentModule instances with the update_fcn provided.
Performs generic update by visiting StudentModule instances with the update_fcn provided.
...
@@ -161,7 +161,7 @@ def _save_course_task(course_task):
...
@@ -161,7 +161,7 @@ def _save_course_task(course_task):
course_task
.
save
()
course_task
.
save
()
def
_update_problem_module_state
(
entry_id
,
course_id
,
module_state_key
,
student_ident
,
update_fcn
,
action_name
,
filter_fcn
,
def
update_problem_module_state
(
entry_id
,
update_fcn
,
action_name
,
filter_fcn
,
xmodule_instance_args
):
xmodule_instance_args
):
"""
"""
Performs generic update by visiting StudentModule instances with the update_fcn provided.
Performs generic update by visiting StudentModule instances with the update_fcn provided.
...
@@ -195,15 +195,20 @@ def _update_problem_module_state(entry_id, course_id, module_state_key, student_
...
@@ -195,15 +195,20 @@ def _update_problem_module_state(entry_id, course_id, module_state_key, student_
result object that Celery creates.
result object that Celery creates.
"""
"""
task_id
=
current_task
.
request
.
id
fmt
=
'Starting to update problem modules as task "{task_id}": course "{course_id}" problem "{state_key}": nothing {action} yet'
TASK_LOG
.
info
(
fmt
.
format
(
task_id
=
task_id
,
course_id
=
course_id
,
state_key
=
module_state_key
,
action
=
action_name
))
# get the InstructorTask to be updated. If this fails, then let the exception return to Celery.
# get the InstructorTask to be updated. If this fails, then let the exception return to Celery.
# There's no point in catching it here.
# There's no point in catching it here.
entry
=
InstructorTask
.
objects
.
get
(
pk
=
entry_id
)
entry
=
InstructorTask
.
objects
.
get
(
pk
=
entry_id
)
entry
.
task_id
=
task_id
_save_course_task
(
entry
)
# get inputs to use in this task from the entry:
task_id
=
entry
.
task_id
course_id
=
entry
.
course_id
task_input
=
json
.
loads
(
entry
.
task_input
)
module_state_key
=
task_input
.
get
(
'problem_url'
)
student_ident
=
task_input
[
'student'
]
if
'student'
in
task_input
else
None
fmt
=
'Starting to update problem modules as task "{task_id}": course "{course_id}" problem "{state_key}": nothing {action} yet'
TASK_LOG
.
info
(
fmt
.
format
(
task_id
=
task_id
,
course_id
=
course_id
,
state_key
=
module_state_key
,
action
=
action_name
))
# add task_id to xmodule_instance_args, so that it can be output with tracking info:
# add task_id to xmodule_instance_args, so that it can be output with tracking info:
if
xmodule_instance_args
is
not
None
:
if
xmodule_instance_args
is
not
None
:
...
@@ -212,6 +217,16 @@ def _update_problem_module_state(entry_id, course_id, module_state_key, student_
...
@@ -212,6 +217,16 @@ def _update_problem_module_state(entry_id, course_id, module_state_key, student_
# now that we have an entry we can try to catch failures:
# now that we have an entry we can try to catch failures:
task_progress
=
None
task_progress
=
None
try
:
try
:
# check that the task_id submitted in the InstructorTask matches the current task
# that is running.
request_task_id
=
current_task
.
request
.
id
if
task_id
!=
request_task_id
:
fmt
=
'Requested task "{task_id}" did not match actual task "{actual_id}"'
message
=
fmt
.
format
(
task_id
=
task_id
,
course_id
=
course_id
,
state_key
=
module_state_key
,
actual_id
=
request_task_id
)
TASK_LOG
.
error
(
message
)
raise
UpdateProblemModuleStateError
(
message
)
# now do the work:
with
dog_stats_api
.
timer
(
'courseware.tasks.module.{0}.overall_time'
.
format
(
action_name
)):
with
dog_stats_api
.
timer
(
'courseware.tasks.module.{0}.overall_time'
.
format
(
action_name
)):
task_progress
=
_perform_module_state_update
(
course_id
,
module_state_key
,
student_ident
,
update_fcn
,
task_progress
=
_perform_module_state_update
(
course_id
,
module_state_key
,
student_ident
,
update_fcn
,
action_name
,
filter_fcn
,
xmodule_instance_args
)
action_name
,
filter_fcn
,
xmodule_instance_args
)
...
@@ -280,7 +295,7 @@ def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule
...
@@ -280,7 +295,7 @@ def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule
@transaction.autocommit
@transaction.autocommit
def
_
rescore_problem_module_state
(
module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
def
rescore_problem_module_state
(
module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
'''
'''
Takes an XModule descriptor and a corresponding StudentModule object, and
Takes an XModule descriptor and a corresponding StudentModule object, and
performs rescoring on the student's problem submission.
performs rescoring on the student's problem submission.
...
@@ -330,7 +345,7 @@ def _rescore_problem_module_state(module_descriptor, student_module, xmodule_ins
...
@@ -330,7 +345,7 @@ def _rescore_problem_module_state(module_descriptor, student_module, xmodule_ins
@transaction.autocommit
@transaction.autocommit
def
_reset_problem
_attempts_module_state
(
_module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
def
reset
_attempts_module_state
(
_module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
"""
"""
Resets problem attempts to zero for specified `student_module`.
Resets problem attempts to zero for specified `student_module`.
...
@@ -356,7 +371,7 @@ def _reset_problem_attempts_module_state(_module_descriptor, student_module, xmo
...
@@ -356,7 +371,7 @@ def _reset_problem_attempts_module_state(_module_descriptor, student_module, xmo
@transaction.autocommit
@transaction.autocommit
def
_
delete_problem_module_state
(
_module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
def
delete_problem_module_state
(
_module_descriptor
,
student_module
,
xmodule_instance_args
=
None
):
"""
"""
Delete the StudentModule entry.
Delete the StudentModule entry.
...
...
lms/djangoapps/instructor_task/tests/test_api.py
View file @
a0dcc97e
...
@@ -24,7 +24,7 @@ from instructor_task.api import (get_running_instructor_tasks,
...
@@ -24,7 +24,7 @@ from instructor_task.api import (get_running_instructor_tasks,
submit_delete_problem_state_for_all_students
)
submit_delete_problem_state_for_all_students
)
from
instructor_task.api_helper
import
(
QUEUING
,
from
instructor_task.api_helper
import
(
QUEUING
,
AlreadyRunningError
,
#
AlreadyRunningError,
encode_problem_and_student_input
,
encode_problem_and_student_input
,
)
)
...
@@ -61,12 +61,12 @@ class TaskSubmitTestCase(TestCase):
...
@@ -61,12 +61,12 @@ class TaskSubmitTestCase(TestCase):
task_input
,
task_key
=
encode_problem_and_student_input
(
self
.
problem_url
,
student
)
task_input
,
task_key
=
encode_problem_and_student_input
(
self
.
problem_url
,
student
)
instructor_task
=
InstructorTaskFactory
.
create
(
course_id
=
TEST_COURSE_ID
,
instructor_task
=
InstructorTaskFactory
.
create
(
course_id
=
TEST_COURSE_ID
,
requester
=
self
.
instructor
,
requester
=
self
.
instructor
,
task_input
=
json
.
dumps
(
task_input
),
task_input
=
json
.
dumps
(
task_input
),
task_key
=
task_key
,
task_key
=
task_key
,
task_id
=
task_id
,
task_id
=
task_id
,
task_state
=
task_state
,
task_state
=
task_state
,
task_output
=
progress_json
)
task_output
=
progress_json
)
return
instructor_task
return
instructor_task
def
_create_failure_entry
(
self
):
def
_create_failure_entry
(
self
):
...
@@ -101,6 +101,7 @@ class TaskSubmitTestCase(TestCase):
...
@@ -101,6 +101,7 @@ class TaskSubmitTestCase(TestCase):
self
.
assertEquals
(
set
(
task_ids
),
set
(
progress_task_ids
))
self
.
assertEquals
(
set
(
task_ids
),
set
(
progress_task_ids
))
def
_get_instructor_task_status
(
self
,
task_id
):
def
_get_instructor_task_status
(
self
,
task_id
):
"""Returns status corresponding to task_id via api method."""
request
=
Mock
()
request
=
Mock
()
request
.
REQUEST
=
{
'task_id'
:
task_id
}
request
.
REQUEST
=
{
'task_id'
:
task_id
}
return
instructor_task_status
(
request
)
return
instructor_task_status
(
request
)
...
...
lms/djangoapps/instructor_task/tests/test_integration.py
View file @
a0dcc97e
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
Integration Test for LMS instructor-initiated background tasks
Integration Test for LMS instructor-initiated background tasks
Runs tasks on answers to course problems to validate that code
Runs tasks on answers to course problems to validate that code
paths actually work.
paths actually work.
"""
"""
import
logging
import
logging
...
@@ -32,7 +32,6 @@ from instructor_task.api import (submit_rescore_problem_for_all_students,
...
@@ -32,7 +32,6 @@ from instructor_task.api import (submit_rescore_problem_for_all_students,
submit_reset_problem_attempts_for_all_students
,
submit_reset_problem_attempts_for_all_students
,
submit_delete_problem_state_for_all_students
)
submit_delete_problem_state_for_all_students
)
from
instructor_task.models
import
InstructorTask
from
instructor_task.models
import
InstructorTask
from
instructor_task.tests.factories
import
InstructorTaskFactory
from
instructor_task.views
import
instructor_task_status
from
instructor_task.views
import
instructor_task_status
...
@@ -235,6 +234,7 @@ class TestRescoringBase(LoginEnrollmentTestCase, ModuleStoreTestCase):
...
@@ -235,6 +234,7 @@ class TestRescoringBase(LoginEnrollmentTestCase, ModuleStoreTestCase):
self
.
assertGreater
(
len
(
state
[
'student_answers'
]),
0
)
self
.
assertGreater
(
len
(
state
[
'student_answers'
]),
0
)
def
get_task_status
(
self
,
task_id
):
def
get_task_status
(
self
,
task_id
):
"""Use api method to fetch task status, using mock request."""
mock_request
=
Mock
()
mock_request
=
Mock
()
mock_request
.
REQUEST
=
{
'task_id'
:
task_id
}
mock_request
.
REQUEST
=
{
'task_id'
:
task_id
}
response
=
instructor_task_status
(
mock_request
)
response
=
instructor_task_status
(
mock_request
)
...
...
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