如果用户卸载,如何停止 celery 任务?

问题描述 投票:0回答:1

我的网站允许用户翻译文件。我想添加一个故障保护,以防用户决定卸载网页(无论是重新加载、导航离开还是关闭选项卡)。我的后端是 django 加 celery[redis]。目前,在用户开始翻译任务后,我的前端每 5 秒轮询一次后端,以查看任务是否仍在运行。下面是对应的JS供参考:

function pollTaskStatus(taskId) {
    currentTaskId = taskId;
    console.log(currentTaskId)
    pollInterval = setInterval(() => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function() {
            if (xhr.status == 200) {
                const response = JSON.parse(xhr.responseText);
                if (response.status === 'completed') {
                    console.log('sent');
                    showTranslationComplete(response);
                    clearInterval(pollInterval); // Stop polling once completed
                    isTranslating = false; // Set to false when translation is complete
                }
            } else {
                showError('An error occurred.');
                clearInterval(pollInterval); // Stop polling on error
                isTranslating = false; // Set to false on errors
            }
        };
        xhr.onerror = function() {
            showError('Connection error. Please check your network connection and try again.');
            clearInterval(pollInterval); // Stop polling on network error
            isTranslating = false; // Set to false on network error
            
        };
        xhr.open('GET', `/translate/poll_task_status/${taskId}/`, true);
        xhr.send();
    }, 5000); // Poll every 5 seconds
}

我知道在卸载事件期间/之后运行函数是不可靠的,所以我避免了这种情况。任何建议表示赞赏。

javascript python django celery
1个回答
0
投票

尝试一下并检查它是否有效?如果需要的话进行一些修改。

window.addEventListener('beforeunload', function (e) {
    if (isTranslating) {
        // Show the confirmation prompt
        const confirmationMessage = 'Translation in progress. Are you sure you want to leave?';
        e.preventDefault();
        e.returnValue = confirmationMessage;

        // The return value is needed for the browser to show the confirmation prompt
        return confirmationMessage;
    }
});

window.addEventListener('unload', function (e) {
    if (isTranslating) {
        // If the user confirmed navigation, stop the task
        stopTranslation();
    }
});

function stopTranslation() {
    if (isTranslating && currentTaskId) {
        // Cancel the polling
        clearInterval(pollInterval);

        // Create an XMLHttpRequest object
        const xhr = new XMLHttpRequest();

        // Set up the onload event handler
        xhr.onload = function() {
            if (xhr.status === 200) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    if (response.status === 'stopped') {
                        console.log('Translation stopped successfully');
                        isTranslating = false;
                        currentTaskId = null;
                        showTranslationStopped(); // Update UI to reflect the stopped state
                    } else {
                        console.error('Unexpected response:', response);
                    }
                } catch (e) {
                    console.error('Error parsing response JSON:', e);
                }
            } else {
                console.error('Failed to stop translation. Status:', xhr.status);
            }
        };

        // Set up the onerror event handler
        xhr.onerror = function() {
            console.error('Connection error while trying to stop translation');
        };

        // Open a POST request to the stop_task endpoint
        xhr.open('POST', `/translate/stop_task/${currentTaskId}/`, true);

        // Set the appropriate headers (CSRF token for Django)
        xhr.setRequestHeader('X-CSRFToken', getCsrfToken());
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

        // Send the request
        xhr.send();
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.