forked from forgejo/forgejo
Make archival asynchronous
The prime benefit being sought here is for large archives to not clog up the rendering process and cause unsightly proxy timeouts. As a secondary benefit, archive-in-progress is moved out of the way into a /tmp file so that new archival requests for the same commit will not get fulfilled based on an archive that isn't yet finished. This asynchronous system is fairly primitive; request comes in, we'll spawn off a new goroutine to handle it, then we'll mark it as done. Status requests will see if the file exists in the final location, and report the archival as done when it exists. Fixes #11265
This commit is contained in:
parent
a104864da2
commit
64ac8440a7
43 changed files with 1216 additions and 85 deletions
|
@ -698,6 +698,86 @@ function initIssueComments() {
|
|||
});
|
||||
}
|
||||
|
||||
function initArchiveStatusChecker($target, url, statusUrl) {
|
||||
$.ajax({
|
||||
url: statusUrl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
_csrf: csrf,
|
||||
},
|
||||
complete(xhr) {
|
||||
if (xhr.status === 200) {
|
||||
if (!xhr.responseJSON) {
|
||||
$target.closest('.dropdown').children('i').removeClass('loading');
|
||||
return;
|
||||
}
|
||||
|
||||
if (xhr.responseJSON.complete) {
|
||||
// Null out the status URL. We don't need to query status again.
|
||||
// getArchive() will clear the loading indicator here, as needed.
|
||||
getArchive($target, url, null);
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
initArchiveStatusChecker($target, url, statusUrl);
|
||||
}, 2000);
|
||||
} else {
|
||||
$target.closest('.dropdown').children('i').removeClass('loading');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getArchive($target, url, statusUrl) {
|
||||
$.ajax({
|
||||
url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
_csrf: csrf,
|
||||
},
|
||||
complete(xhr) {
|
||||
if (xhr.status === 200) {
|
||||
if (!xhr.responseJSON) {
|
||||
// XXX Shouldn't happen?
|
||||
$target.closest('.dropdown').children('i').removeClass('loading');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xhr.responseJSON.complete && statusUrl !== null) {
|
||||
$target.closest('.dropdown').children('i').addClass('loading');
|
||||
setTimeout(() => {
|
||||
initArchiveStatusChecker($target, url, statusUrl);
|
||||
}, 2000);
|
||||
} else {
|
||||
// We don't need to continue checking.
|
||||
$target.closest('.dropdown').children('i').removeClass('loading');
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initArchiveLinks() {
|
||||
if ($('.archive-link').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.archive-link').on('click', function (event) {
|
||||
const url = $(this).data('url');
|
||||
if (typeof url === 'undefined') {
|
||||
return;
|
||||
}
|
||||
const statusUrl = $(this).data('status');
|
||||
if (typeof statusUrl === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
getArchive($(event.target), url, statusUrl);
|
||||
});
|
||||
}
|
||||
|
||||
async function initRepository() {
|
||||
if ($('.repository').length === 0) {
|
||||
return;
|
||||
|
@ -2565,6 +2645,7 @@ $(document).ready(async () => {
|
|||
|
||||
initCommentForm();
|
||||
initInstall();
|
||||
initArchiveLinks();
|
||||
initRepository();
|
||||
initMigration();
|
||||
initWikiForm();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue