Add SSE streaming endpoint for workflow events #33

Closed
opened 2026-09-26 09:47:51 +00:00 by rock · 0 comments
Owner

Description

Add Server-Sent Events endpoint to stream Temporal workflow execution events to the frontend in real-time.

Endpoint

GET /v1/poimen/executions/:id/stream
Authorization: Bearer <JWT>
Accept: text/event-stream

SSE Event Format

event: activity_started
data: {"node_id": "clone", "activity": "CloneRepoActivity", "timestamp": "..."}

event: activity_completed
data: {"node_id": "clone", "activity": "CloneRepoActivity", "output": {}, "duration_ms": 2500}

event: activity_failed
data: {"node_id": "scan", "activity": "SecurityScan", "error": "timeout", "attempt": 2}

event: workflow_completed
data: {"status": "COMPLETED", "final_output": {}}

event: heartbeat
data: {"timestamp": "..."}

Implementation

  • Long-lived HTTP connection with Content-Type: text/event-stream
  • Poll Temporal GetWorkflowExecutionHistory every 2s
  • Track last seen event_id, only send new events
  • Send heartbeat every 15s to keep connection alive
  • Close stream on workflow completion or client disconnect
  • Respect JWT expiry — close stream if token expires
  • Map Temporal history event types to semantic SSE events:
    • ActivityTaskStarted → activity_started
    • ActivityTaskCompleted → activity_completed
    • ActivityTaskFailed → activity_failed
    • WorkflowExecutionCompleted → workflow_completed

Acceptance Criteria

  • SSE stream opens and receives events in real-time
  • Events map to Temporal history event types
  • Stream closes cleanly on workflow completion
  • Heartbeat keeps connection alive
  • JWT validation on connection open
## Description Add Server-Sent Events endpoint to stream Temporal workflow execution events to the frontend in real-time. ## Endpoint ``` GET /v1/poimen/executions/:id/stream Authorization: Bearer <JWT> Accept: text/event-stream ``` ## SSE Event Format ``` event: activity_started data: {"node_id": "clone", "activity": "CloneRepoActivity", "timestamp": "..."} event: activity_completed data: {"node_id": "clone", "activity": "CloneRepoActivity", "output": {}, "duration_ms": 2500} event: activity_failed data: {"node_id": "scan", "activity": "SecurityScan", "error": "timeout", "attempt": 2} event: workflow_completed data: {"status": "COMPLETED", "final_output": {}} event: heartbeat data: {"timestamp": "..."} ``` ## Implementation - Long-lived HTTP connection with `Content-Type: text/event-stream` - Poll Temporal `GetWorkflowExecutionHistory` every 2s - Track last seen `event_id`, only send new events - Send `heartbeat` every 15s to keep connection alive - Close stream on workflow completion or client disconnect - Respect JWT expiry — close stream if token expires - Map Temporal history event types to semantic SSE events: - `ActivityTaskStarted` → `activity_started` - `ActivityTaskCompleted` → `activity_completed` - `ActivityTaskFailed` → `activity_failed` - `WorkflowExecutionCompleted` → `workflow_completed` ## Acceptance Criteria - [ ] SSE stream opens and receives events in real-time - [ ] Events map to Temporal history event types - [ ] Stream closes cleanly on workflow completion - [ ] Heartbeat keeps connection alive - [ ] JWT validation on connection open
rock closed this issue 2026-09-26 10:50:20 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: riotpiao-poimen/homelab-frontend#33