Enable tiled_vae to prevent OOM on portrait images
Some checks failed
Build and Push Docker Image / build (push) Failing after 29m0s
Some checks failed
Build and Push Docker Image / build (push) Failing after 29m0s
Also add async polling to HTML test page for long-running jobs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
138
test-runpod.html
138
test-runpod.html
@@ -456,6 +456,107 @@
|
||||
document.getElementById('status').classList.remove('show');
|
||||
}
|
||||
|
||||
async function pollForCompletion(endpointId, jobId, apiKey, startTime) {
|
||||
const statusUrl = `https://api.runpod.ai/v2/${endpointId}/status/${jobId}`;
|
||||
const maxPolls = 120; // 10 minutes with 5s intervals
|
||||
let pollCount = 0;
|
||||
|
||||
while (pollCount < maxPolls) {
|
||||
pollCount++;
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);
|
||||
showStatus(`⏳ Generating video... (${elapsed}s elapsed, poll #${pollCount})`, 'info');
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
|
||||
|
||||
try {
|
||||
const response = await fetch(statusUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Update JSON output
|
||||
document.getElementById('jsonOutput').innerHTML =
|
||||
'<strong>Raw Response:</strong><pre>' +
|
||||
JSON.stringify(result, null, 2) +
|
||||
'</pre>';
|
||||
|
||||
if (result.status === 'COMPLETED' || result.status === 'FAILED') {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Still in progress, continue polling
|
||||
} catch (error) {
|
||||
console.error('Poll error:', error);
|
||||
// Continue polling despite errors
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Timeout: Job did not complete within 10 minutes');
|
||||
}
|
||||
|
||||
async function handleResult(result, startTime, endpointId, apiKey) {
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
|
||||
|
||||
// If still in progress, poll for completion
|
||||
if (result.status === 'IN_PROGRESS' || result.status === 'IN_QUEUE') {
|
||||
showStatus(`⏳ Job ${result.id} is ${result.status}. Polling for completion...`, 'info');
|
||||
result = await pollForCompletion(endpointId, result.id, apiKey, startTime);
|
||||
|
||||
// Update JSON output with final result
|
||||
document.getElementById('jsonOutput').innerHTML =
|
||||
'<strong>Raw Response:</strong><pre>' +
|
||||
JSON.stringify(result, null, 2) +
|
||||
'</pre>';
|
||||
}
|
||||
|
||||
const finalElapsed = ((Date.now() - startTime) / 1000).toFixed(2);
|
||||
|
||||
if (result.status === 'COMPLETED' && result.output) {
|
||||
showStatus(`✅ Video generated successfully in ${finalElapsed}s`, 'success');
|
||||
|
||||
const outputContainer = document.getElementById('outputContainer');
|
||||
|
||||
if (result.output.video) {
|
||||
// Base64 video
|
||||
const videoElem = document.createElement('video');
|
||||
videoElem.className = 'output-video';
|
||||
videoElem.controls = true;
|
||||
videoElem.autoplay = true;
|
||||
videoElem.loop = true;
|
||||
videoElem.src = 'data:video/mp4;base64,' + result.output.video;
|
||||
outputContainer.appendChild(videoElem);
|
||||
} else if (result.output.image) {
|
||||
// Base64 image
|
||||
const imgElem = document.createElement('img');
|
||||
imgElem.className = 'output-video';
|
||||
imgElem.src = 'data:image/png;base64,' + result.output.image;
|
||||
outputContainer.appendChild(imgElem);
|
||||
} else if (result.output.file_path) {
|
||||
// File path (large output)
|
||||
const fileInfo = document.createElement('div');
|
||||
fileInfo.className = 'status info show';
|
||||
fileInfo.innerHTML = `
|
||||
<strong>Large output saved to:</strong><br>
|
||||
<code>${result.output.file_path}</code><br><br>
|
||||
<em>File is too large to display (>10MB). Access it on your RunPod volume.</em>
|
||||
`;
|
||||
outputContainer.appendChild(fileInfo);
|
||||
}
|
||||
} else if (result.status === 'FAILED') {
|
||||
showStatus('❌ Generation failed: ' + (result.error || 'Unknown error'), 'error');
|
||||
} else {
|
||||
showStatus('⚠️ Unexpected response status: ' + result.status, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function submitRequest() {
|
||||
// Validation
|
||||
const endpointId = document.getElementById('endpointId').value.trim();
|
||||
@@ -531,42 +632,7 @@
|
||||
'</pre>';
|
||||
|
||||
// Handle response
|
||||
if (result.status === 'COMPLETED' && result.output) {
|
||||
showStatus(`✅ Video generated successfully in ${elapsed}s`, 'success');
|
||||
|
||||
const outputContainer = document.getElementById('outputContainer');
|
||||
|
||||
if (result.output.video) {
|
||||
// Base64 video
|
||||
const videoElem = document.createElement('video');
|
||||
videoElem.className = 'output-video';
|
||||
videoElem.controls = true;
|
||||
videoElem.autoplay = true;
|
||||
videoElem.loop = true;
|
||||
videoElem.src = 'data:video/mp4;base64,' + result.output.video;
|
||||
outputContainer.appendChild(videoElem);
|
||||
} else if (result.output.image) {
|
||||
// Base64 image
|
||||
const imgElem = document.createElement('img');
|
||||
imgElem.className = 'output-video';
|
||||
imgElem.src = 'data:image/png;base64,' + result.output.image;
|
||||
outputContainer.appendChild(imgElem);
|
||||
} else if (result.output.file_path) {
|
||||
// File path (large output)
|
||||
const fileInfo = document.createElement('div');
|
||||
fileInfo.className = 'status info show';
|
||||
fileInfo.innerHTML = `
|
||||
<strong>Large output saved to:</strong><br>
|
||||
<code>${result.output.file_path}</code><br><br>
|
||||
<em>File is too large to display (>10MB). Access it on your RunPod volume.</em>
|
||||
`;
|
||||
outputContainer.appendChild(fileInfo);
|
||||
}
|
||||
} else if (result.status === 'FAILED') {
|
||||
showStatus('❌ Generation failed: ' + (result.error || 'Unknown error'), 'error');
|
||||
} else {
|
||||
showStatus('⚠️ Unexpected response status: ' + result.status, 'error');
|
||||
}
|
||||
await handleResult(result, startTime, endpointId, apiKey);
|
||||
|
||||
} catch (error) {
|
||||
showStatus('❌ Error: ' + error.message, 'error');
|
||||
|
||||
Reference in New Issue
Block a user