MDL-74911 assignfeedback_editpdf: per-assignment conversion poll lock
The lock ensures that multiple conversions do not happen for the same assignment submission. Otherwise, subsequent conversions will fail when trying to save the converted file.
This commit is contained in:
@@ -68,7 +68,22 @@ if ($action === 'pollconversions') {
|
||||
$draft = false;
|
||||
}
|
||||
|
||||
$response = (object) [
|
||||
// Get a lock for the PDF/Image conversion of the assignment files.
|
||||
$lockfactory = \core\lock\lock_config::get_lock_factory('assignfeedback_editpdf_pollconversions');
|
||||
$resource = "user:${userid},assignmentid:${assignmentid},attemptnumber:${attemptnumber}";
|
||||
$lock = $lockfactory->get_lock($resource, 0);
|
||||
|
||||
// Could not get lock, send back JSON to poll again.
|
||||
if (!$lock) {
|
||||
echo json_encode([
|
||||
'status' => 0
|
||||
]);
|
||||
die();
|
||||
}
|
||||
|
||||
// Obtained lock, now process the assignment conversion.
|
||||
try {
|
||||
$response = (object) [
|
||||
'status' => -1,
|
||||
'filecount' => 0,
|
||||
'pagecount' => 0,
|
||||
@@ -77,70 +92,76 @@ if ($action === 'pollconversions') {
|
||||
'pages' => [],
|
||||
];
|
||||
|
||||
$combineddocument = document_services::get_combined_document_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$response->status = $combineddocument->get_status();
|
||||
$response->filecount = $combineddocument->get_document_count();
|
||||
|
||||
$readystatuslist = [combined_document::STATUS_READY, combined_document::STATUS_READY_PARTIAL];
|
||||
$completestatuslist = [combined_document::STATUS_COMPLETE, combined_document::STATUS_FAILED];
|
||||
|
||||
if (in_array($response->status, $readystatuslist)) {
|
||||
// It seems that the files for this submission haven't been combined in cron yet.
|
||||
// Try to combine them in the user session.
|
||||
$combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$combineddocument = document_services::get_combined_document_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$response->status = $combineddocument->get_status();
|
||||
$response->filecount = $combineddocument->get_document_count();
|
||||
}
|
||||
|
||||
if (in_array($response->status, $completestatuslist)) {
|
||||
$pages = document_services::get_page_images_for_attempt($assignment,
|
||||
$userid,
|
||||
$attemptnumber,
|
||||
$readonly);
|
||||
$readystatuslist = [combined_document::STATUS_READY, combined_document::STATUS_READY_PARTIAL];
|
||||
$completestatuslist = [combined_document::STATUS_COMPLETE, combined_document::STATUS_FAILED];
|
||||
|
||||
$response->pagecount = $combineddocument->get_page_count();
|
||||
|
||||
$grade = $assignment->get_user_grade($userid, true, $attemptnumber);
|
||||
|
||||
// The readonly files are stored in a different file area.
|
||||
$filearea = document_services::PAGE_IMAGE_FILEAREA;
|
||||
if ($readonly) {
|
||||
$filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA;
|
||||
if (in_array($response->status, $readystatuslist)) {
|
||||
// It seems that the files for this submission haven't been combined in cron yet.
|
||||
// Try to combine them in the user session.
|
||||
$combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$response->status = $combineddocument->get_status();
|
||||
$response->filecount = $combineddocument->get_document_count();
|
||||
}
|
||||
$response->partial = $combineddocument->is_partial_conversion();
|
||||
|
||||
foreach ($pages as $id => $pagefile) {
|
||||
$index = count($response->pages);
|
||||
$page = new stdClass();
|
||||
$comments = page_editor::get_comments($grade->id, $index, $draft);
|
||||
$page->url = moodle_url::make_pluginfile_url($context->id,
|
||||
'assignfeedback_editpdf',
|
||||
$filearea,
|
||||
$grade->id,
|
||||
'/',
|
||||
$pagefile->get_filename())->out();
|
||||
$page->comments = $comments;
|
||||
if ($imageinfo = $pagefile->get_imageinfo()) {
|
||||
$page->width = $imageinfo['width'];
|
||||
$page->height = $imageinfo['height'];
|
||||
} else {
|
||||
$page->width = 0;
|
||||
$page->height = 0;
|
||||
if (in_array($response->status, $completestatuslist)) {
|
||||
$pages = document_services::get_page_images_for_attempt($assignment,
|
||||
$userid,
|
||||
$attemptnumber,
|
||||
$readonly);
|
||||
|
||||
$response->pagecount = $combineddocument->get_page_count();
|
||||
|
||||
$grade = $assignment->get_user_grade($userid, true, $attemptnumber);
|
||||
|
||||
// The readonly files are stored in a different file area.
|
||||
$filearea = document_services::PAGE_IMAGE_FILEAREA;
|
||||
if ($readonly) {
|
||||
$filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA;
|
||||
}
|
||||
$annotations = page_editor::get_annotations($grade->id, $index, $draft);
|
||||
$page->annotations = $annotations;
|
||||
$response->pages[] = $page;
|
||||
}
|
||||
$response->partial = $combineddocument->is_partial_conversion();
|
||||
|
||||
$component = 'assignfeedback_editpdf';
|
||||
$filearea = document_services::PAGE_IMAGE_FILEAREA;
|
||||
$filepath = '/';
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_directory_files($context->id, $component, $filearea, $grade->id, $filepath);
|
||||
$response->pageready = count($files);
|
||||
foreach ($pages as $id => $pagefile) {
|
||||
$index = count($response->pages);
|
||||
$page = new stdClass();
|
||||
$comments = page_editor::get_comments($grade->id, $index, $draft);
|
||||
$page->url = moodle_url::make_pluginfile_url($context->id,
|
||||
'assignfeedback_editpdf',
|
||||
$filearea,
|
||||
$grade->id,
|
||||
'/',
|
||||
$pagefile->get_filename())->out();
|
||||
$page->comments = $comments;
|
||||
if ($imageinfo = $pagefile->get_imageinfo()) {
|
||||
$page->width = $imageinfo['width'];
|
||||
$page->height = $imageinfo['height'];
|
||||
} else {
|
||||
$page->width = 0;
|
||||
$page->height = 0;
|
||||
}
|
||||
$annotations = page_editor::get_annotations($grade->id, $index, $draft);
|
||||
$page->annotations = $annotations;
|
||||
$response->pages[] = $page;
|
||||
}
|
||||
|
||||
$component = 'assignfeedback_editpdf';
|
||||
$filearea = document_services::PAGE_IMAGE_FILEAREA;
|
||||
$filepath = '/';
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_directory_files($context->id, $component, $filearea, $grade->id, $filepath);
|
||||
$response->pageready = count($files);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Release lock, and re-throw exception.
|
||||
$lock->release();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
$lock->release();
|
||||
die();
|
||||
} else if ($action == 'savepage') {
|
||||
require_capability('mod/assign:grade', $context);
|
||||
|
||||
Reference in New Issue
Block a user