feat(#174): Implement SSE endpoint for CLI consumers
Add Server-Sent Events (SSE) endpoint for streaming job events to CLI consumers who prefer HTTP streaming over WebSocket. Endpoint: GET /runner-jobs/:id/events/stream Features: - Database polling (500ms interval) for new events - Keep-alive pings (15s interval) to prevent timeout - Auto-cleanup on connection close or job completion - Authentication required (workspace member) - SSE format: event: <type>\ndata: <json>\n\n Implementation: - Added streamEvents method to RunnerJobsService - Added streamEvents endpoint to RunnerJobsController - Comprehensive unit tests for both controller and service - All quality gates pass (typecheck, lint, build, test) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -297,9 +297,7 @@ describe("RunnerJobsController", () => {
|
|||||||
await controller.streamEvents(jobId, workspaceId, mockRes as never);
|
await controller.streamEvents(jobId, workspaceId, mockRes as never);
|
||||||
|
|
||||||
// Verify error is written to stream
|
// Verify error is written to stream
|
||||||
expect(mockRes.write).toHaveBeenCalledWith(
|
expect(mockRes.write).toHaveBeenCalledWith(expect.stringContaining("Job not found"));
|
||||||
expect.stringContaining("Job not found")
|
|
||||||
);
|
|
||||||
expect(mockRes.end).toHaveBeenCalled();
|
expect(mockRes.end).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
# Issue #174: SSE endpoint for CLI consumers
|
# Issue #174: SSE endpoint for CLI consumers
|
||||||
|
|
||||||
## Objective
|
## Objective
|
||||||
|
|
||||||
Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streaming over WebSocket.
|
Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streaming over WebSocket.
|
||||||
|
|
||||||
## Approach
|
## Approach
|
||||||
|
|
||||||
1. Review existing JobEventsService from #169
|
1. Review existing JobEventsService from #169
|
||||||
2. Create SSE endpoint in runner-jobs controller
|
2. Create SSE endpoint in runner-jobs controller
|
||||||
3. Implement event streaming from Valkey Pub/Sub
|
3. Implement event streaming from Valkey Pub/Sub
|
||||||
@@ -12,6 +14,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
6. Follow TDD: Write tests first, then implementation
|
6. Follow TDD: Write tests first, then implementation
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
|
|
||||||
- [x] Review existing code structure
|
- [x] Review existing code structure
|
||||||
- [x] Write failing tests (RED)
|
- [x] Write failing tests (RED)
|
||||||
- [x] Implement SSE endpoint (GREEN)
|
- [x] Implement SSE endpoint (GREEN)
|
||||||
@@ -21,6 +24,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
- [ ] Commit changes
|
- [ ] Commit changes
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
- [x] Unit tests for SSE endpoint (controller)
|
- [x] Unit tests for SSE endpoint (controller)
|
||||||
- [x] Unit tests for streaming service method
|
- [x] Unit tests for streaming service method
|
||||||
- [x] Tests for authentication (via guards)
|
- [x] Tests for authentication (via guards)
|
||||||
@@ -30,7 +34,9 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
### Implementation Summary
|
### Implementation Summary
|
||||||
|
|
||||||
**Files Modified:**
|
**Files Modified:**
|
||||||
|
|
||||||
1. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.ts`
|
1. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.ts`
|
||||||
- Added `streamEvents` endpoint: GET /runner-jobs/:id/events/stream
|
- Added `streamEvents` endpoint: GET /runner-jobs/:id/events/stream
|
||||||
- Sets SSE headers and delegates to service
|
- Sets SSE headers and delegates to service
|
||||||
@@ -52,6 +58,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
- Tests job completion, not found, and connection cleanup
|
- Tests job completion, not found, and connection cleanup
|
||||||
|
|
||||||
**Key Features:**
|
**Key Features:**
|
||||||
|
|
||||||
- Database polling (500ms interval) for events
|
- Database polling (500ms interval) for events
|
||||||
- Keep-alive pings (15s interval) to prevent timeout
|
- Keep-alive pings (15s interval) to prevent timeout
|
||||||
- SSE format: `event: <type>\ndata: <json>\n\n`
|
- SSE format: `event: <type>\ndata: <json>\n\n`
|
||||||
@@ -59,6 +66,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
- Authentication required (workspace member)
|
- Authentication required (workspace member)
|
||||||
|
|
||||||
**Quality Gates:**
|
**Quality Gates:**
|
||||||
|
|
||||||
- All tests pass (1391 passed)
|
- All tests pass (1391 passed)
|
||||||
- Typecheck passes
|
- Typecheck passes
|
||||||
- Lint passes (with pre-existing bridge/parser errors)
|
- Lint passes (with pre-existing bridge/parser errors)
|
||||||
@@ -67,6 +75,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
### Code Review Findings
|
### Code Review Findings
|
||||||
|
|
||||||
1. JobEventsService exists and provides event querying via `getEventsByJobId`
|
1. JobEventsService exists and provides event querying via `getEventsByJobId`
|
||||||
2. LLM controller has SSE implementation pattern using Express Response
|
2. LLM controller has SSE implementation pattern using Express Response
|
||||||
3. Event types defined in `job-events/event-types.ts`
|
3. Event types defined in `job-events/event-types.ts`
|
||||||
@@ -75,6 +84,7 @@ Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streamin
|
|||||||
6. SSE format: `res.write("data: " + JSON.stringify(data) + "\n\n")`
|
6. SSE format: `res.write("data: " + JSON.stringify(data) + "\n\n")`
|
||||||
|
|
||||||
### Implementation Plan
|
### Implementation Plan
|
||||||
|
|
||||||
1. Add SSE endpoint: GET /runner-jobs/:id/events/stream
|
1. Add SSE endpoint: GET /runner-jobs/:id/events/stream
|
||||||
2. Poll database for new events (since timestamp)
|
2. Poll database for new events (since timestamp)
|
||||||
3. Use keep-alive pings every 15 seconds
|
3. Use keep-alive pings every 15 seconds
|
||||||
|
|||||||
Reference in New Issue
Block a user