Skip to content

feat: Replace polling with SSE for real-time InferenceService updates#160

Open
Prateekbala wants to merge 10 commits intokserve:masterfrom
Prateekbala:sse-feature-new
Open

feat: Replace polling with SSE for real-time InferenceService updates#160
Prateekbala wants to merge 10 commits intokserve:masterfrom
Prateekbala:sse-feature-new

Conversation

@Prateekbala
Copy link
Copy Markdown
Contributor

Summary

Replace inefficient HTTP polling with Server-Sent Events (SSE) for real-time updates from Kubernetes resources. This implementation reduces network traffic, decreases backend load, and provides immediate visibility into resource state changes.

Changes

Backend

  • Added 4 new SSE endpoints leveraging Kubernetes Watch API:

    • /api/sse/namespaces/<namespace>/inferenceservices - Watch all InferenceServices
    • /api/sse/namespaces/<namespace>/inferenceservices/<name> - Watch single InferenceService
    • /api/sse/namespaces/<namespace>/inferenceservices/<name>/events - Watch Kubernetes events
    • /api/sse/namespaces/<namespace>/inferenceservices/<name>/logs - Stream pod logs
  • New SSE module with thread-safe connection manager and watchers

  • Input validation (max 10 components, bounded queues of 500)

  • Automatic backoff on errors with 5-second retry intervals

  • Graceful cleanup on client disconnect

Frontend

  • New SSEService with 4 watch methods matching backend endpoints
  • Updated components with SSE integration + polling fallback:
    • Index page: Watch namespace InferenceServices
    • Server info: Watch single InferenceService + events + logs
    • Events component: Real-time Kubernetes event updates
    • Logs component: Stream component logs
  • Reconnection logic with max 3 attempts
  • Heartbeat handling to detect dead connections

Configuration

  • Added SSE_ENABLED environment variable (default: true) in both deployment configs
  • Fallback to polling if SSE unavailable

Closes #152

@juliusvonkohout
Copy link
Copy Markdown
Contributor

Very interesting @LogicalGuy77

@@ -69,6 +71,7 @@ export class ServerInfoComponent implements OnInit, OnDestroy {
retries: 1,
});
private pollingSubscription = new Subscription();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are replacing polling so this should be removed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is there as a fallback so I think it should be fine

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the default approach for controllers? If server side notifications are guaranteed by Kubernetes, why would we want to keep polling Code. Is it a core feature or only available on some kubernetes? Dead code removal is very important.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Watch API can sometimes fail because of network issues. So I built in automatic reconnection logic — it tries 3 times, and if it still fails, it falls back to polling. This way we get fast real-time updates most of the time with SSE, but if that connection drops, polling takes over so you always get your updates.

Copy link
Copy Markdown
Contributor

@alokdangre alokdangre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this cuases lint errors

Comment thread frontend/src/app/pages/server-info/logs/logs.component.ts Outdated
Comment thread frontend/src/app/pages/server-info/logs/logs.component.ts Outdated
@alokdangre
Copy link
Copy Markdown
Contributor

alokdangre commented Feb 19, 2026

@Prateekbala did you checked locally , can you provide ss?

@LogicalGuy77
Copy link
Copy Markdown
Contributor

@Prateekbala thank you for adding this feature, I will have a look at this next week since I'll be occupied with my exams.

@Prateekbala
Copy link
Copy Markdown
Contributor Author

SSE-implementation I have attached the screenshot.

@Prateekbala
Copy link
Copy Markdown
Contributor Author

@LogicalGuy77 can you please do a final review for this PR

Comment thread config/overlays/kubeflow/kustomization.yaml Outdated
Comment thread frontend/cypress/e2e/index-page.cy.ts Outdated
Comment thread frontend/cypress/e2e/model-deletion.cy.ts Outdated
Comment thread frontend/cypress/e2e/model-edit.cy.ts Outdated
@LogicalGuy77
Copy link
Copy Markdown
Contributor

hey @Prateekbala I'd suggest to write a new cypress test file to test SSE, you can mock kubernetes sent events. Just a simple test should suffice

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the existing HTTP polling mechanism with Server-Sent Events (SSE) for real-time updates from Kubernetes resources, addressing issue #152. It adds new SSE endpoints on the backend that leverage the Kubernetes Watch API, a new frontend SSEService, and updates four components to use SSE with polling fallback. Configuration is controlled via an SSE_ENABLED environment variable.

Changes:

  • Added backend SSE module with 4 streaming endpoints (watchers.py, routes.py, manager.py), a thread-safe connection manager, and Kubernetes Watch-based watchers for InferenceServices, events, and logs.
  • Created frontend SSEService with EventSource-based Observable wrappers and updated IndexComponent, ServerInfoComponent, EventsComponent, and LogsComponent to use SSE with polling fallback.
  • Added SSE_ENABLED configuration to backend, frontend config service, kustomize manifests, and Cypress test fixtures.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
backend/apps/common/sse/__init__.py New SSE module init, exports manager and blueprint
backend/apps/common/sse/manager.py SSEConnectionManager for managing watch streams and client queues
backend/apps/common/sse/watchers.py Kubernetes watchers (InferenceService, Events, Logs) using threading
backend/apps/common/sse/routes.py Flask SSE endpoint route handlers
backend/apps/common/__init__.py Registers SSE blueprint
backend/apps/v1beta1/routes/get.py Adds sseEnabled to config API response
backend/requirements.txt Adds gevent dependency
frontend/src/app/services/sse.service.ts New SSEService with EventSource-based Observable wrappers
frontend/src/app/services/config.service.ts Adds sseEnabled default to config
frontend/src/app/types/config.ts Adds sseEnabled to AppConfig type
frontend/src/app/pages/index/index.component.ts SSE integration for InferenceService list with polling fallback
frontend/src/app/pages/server-info/server-info.component.ts SSE integration for single InferenceService with polling fallback
frontend/src/app/pages/server-info/events/events.component.ts SSE integration for Kubernetes events with polling fallback
frontend/src/app/pages/server-info/logs/logs.component.ts SSE integration for pod logs with polling fallback
frontend/package.json Adds eventsource-polyfill dependency
config/base/kustomization.yaml Adds SSE_ENABLED env var
config/overlays/kubeflow/kustomization.yaml Adds SSE_ENABLED env var
frontend/cypress/e2e/*.cy.ts Updates Cypress tests to mock SSE config

Comment thread backend/apps/common/sse/watchers.py Outdated
Comment thread frontend/src/app/pages/server-info/events/events.component.ts Outdated
Comment thread frontend/package.json Outdated
Comment thread frontend/src/app/pages/index/index.component.ts Outdated
Comment thread backend/requirements.txt
Comment thread frontend/src/app/services/sse.service.ts Outdated
Comment thread backend/apps/common/sse/manager.py Outdated
Comment thread backend/apps/common/sse/routes.py Outdated
Comment thread backend/apps/common/sse/routes.py Outdated
Comment thread frontend/src/app/pages/server-info/logs/logs.component.ts Outdated
@Prateekbala Prateekbala force-pushed the sse-feature-new branch 5 times, most recently from 2343bc2 to ce7bca5 Compare March 9, 2026 21:01
@Prateekbala
Copy link
Copy Markdown
Contributor Author

I have resolved all the copilot reviews ,@LogicalGuy77 can you please look into this.

I have added Cypress e2e tests to cover the SSE functionality. The SSE_ENABLED feature flag was also removed to simplify the code, and that change required additional e2e test fixes to align with the updated behavior which i have made.

Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
Signed-off-by: Prateek Bala <prateekbala28@gmail.com>
@juliusvonkohout
Copy link
Copy Markdown
Contributor

Please fix the conflict and dco tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace polling mechanism with WebSocket/SSE for real-time updates

5 participants