fix: Use SSE streaming in WorkflowExecutePanel to prevent 504 timeout
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / pytest-backend (push) Successful in 5s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s

ROOT CAUSE:
- WorkflowExecutePanel used api.executeWorkflow (synchronous POST)
- Long workflows (10+ nodes, 60-90s) → 504 Gateway Timeout
- Reverse proxy kills request after 60s

SOLUTION:
- Switch to api.executeUnifiedPromptStream (SSE)
- Real-time progress updates during execution
- No timeout (streaming connection stays alive)
- Progress display: X/Y Nodes • Current node label

Changes:
- Replace executeWorkflow with executeUnifiedPromptStream
- Add progress callback for node_complete events
- Add progress state + UI display
- Flexbox column layout for progress bar

Fixes: 504 Gateway Timeout bei langen Workflows im Workflow Designer
This commit is contained in:
Lars 2026-04-13 15:18:50 +02:00
parent 680269e971
commit b1d596e0ab

View File

@ -6,11 +6,10 @@ import { api } from '../../../utils/api'
*
* Features:
* - Execute Button mit Loading State
* - SSE Streaming (kein Timeout bei langen Workflows)
* - Real-time Progress
* - Error Handling
* - Success State
* - Debug Mode Toggle
*
* Part 2: Frontend Execute Integration
*/
export function WorkflowExecutePanel({
currentPrompt,
@ -20,6 +19,7 @@ export function WorkflowExecutePanel({
const [executing, setExecuting] = useState(false)
const [error, setError] = useState(null)
const [debugMode, setDebugMode] = useState(true)
const [progress, setProgress] = useState(null)
const handleExecute = async () => {
if (!currentPrompt || !currentPrompt.slug) {
@ -30,14 +30,28 @@ export function WorkflowExecutePanel({
try {
setExecuting(true)
setError(null)
setProgress({ current: 0, total: 0, label: 'Starte...' })
console.log('🚀 Executing workflow:', currentPrompt.slug)
console.log('🚀 Executing workflow via SSE:', currentPrompt.slug)
const result = await api.executeWorkflow(
const result = await api.executeUnifiedPromptStream(
currentPrompt.slug,
null, // variables (später erweiterbar)
null, // modules
null, // timeframes
debugMode,
false // save (nicht in ai_insights speichern)
false, // save (nicht in ai_insights speichern)
(event) => {
// Progress callback für real-time updates
if (event.type === 'execution_started') {
setProgress({ current: 0, total: 0, label: 'Gestartet...' })
} else if (event.type === 'node_complete') {
setProgress({
current: event.completed_nodes || 0,
total: event.total_nodes || 0,
label: event.node_label || 'Processing...'
})
}
}
)
console.log('✅ Workflow execution completed:', result)
@ -57,10 +71,12 @@ export function WorkflowExecutePanel({
setError(e.message)
} finally {
setExecuting(false)
setProgress(null)
}
}
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
{/* Debug Mode Toggle */}
<label
@ -135,5 +151,29 @@ export function WorkflowExecutePanel({
</div>
)}
</div>
{/* Progress Display */}
{progress && (
<div style={{
padding: '8px 12px',
background: 'var(--surface2)',
borderRadius: '4px',
fontSize: '12px',
color: 'var(--text2)',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}>
<span className="spinner" style={{ width: 12, height: 12 }} />
<span>
{progress.total > 0
? `${progress.current}/${progress.total} Nodes`
: 'Läuft...'
}
{progress.label && `${progress.label}`}
</span>
</div>
)}
</div>
)
}