Data Flow
Read Path
Browser → Handler → Service → K8sRepo
│
┌────────────┴────────────┐
│ │
Informer Cache API Server
(sub-ms, 8 types) (fallback, all types)
- Handler receives GET request
- Service delegates to K8sRepo
- K8sRepo checks Informer cache first (8 core resources)
- If cache miss or resource not cached, falls back to API Server
- Response includes
meta.source("cache" or "apiserver") andmeta.staleflag
Write Path
Browser → Handler → Service → K8sRepo → API Server
│
Informer Watch
│
EventListener
│
WS Hub
│
All Browsers
- Handler receives POST/PUT/DELETE request
- Service validates and delegates to K8sRepo
- K8sRepo calls API Server directly
- API Server applies the change
- Informer Watch detects the change
- EventListener notifies WS Hub
- Hub broadcasts to all connected browsers
- Browsers update automatically (no polling needed)
Real-time Push
The real-time system is fully decoupled:
// EventListener interface — Hub implements this
type EventListener interface {
OnResourceEvent(event ResourceEvent)
}
// Hub: non-blocking receive, drop if channel full
// (frontend has 30s fallback polling)
func (h *Hub) OnResourceEvent(event ResourceEvent) {
select {
case h.broadcast <- marshal(event):
default: // drop, don't block Informer
}
}
Informer Cache Strategy
| Cached (8 types) | On-Demand | Never Cached |
|---|---|---|
| Pods | Jobs | Secrets (security) |
| Deployments | CronJobs | Events (volume) |
| StatefulSets | ConfigMaps | |
| DaemonSets | PVs, PVCs | |
| Services | StorageClasses | |
| Ingresses | NetworkPolicies | |
| Nodes | Roles, RoleBindings | |
| Namespaces | ServiceAccounts |