Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.6 KiB
ADR 002: Dual Data Fetching Strategy (Hooks + ApiProxy)
Status: Accepted
Date: 2026-03-05
Deciders: Development Team
Context
The plugin needs data from two categories of Kubernetes resources:
- Standard resources: Nodes and Pods, for which Headlamp provides reactive
useList()hooks via built-in resource classes. - Custom resources: GpuDevicePlugin CRD (under
deviceplugin.intel.com/v1) and DaemonSet pods with specific labels, for which Headlamp does not have built-in support.
Headlamp provides reactive useList() hooks for standard resource classes but does not have built-in support for custom CRDs. The plugin uses three possible label selectors for DaemonSet pod discovery to handle different deployment configurations.
Decision
Implement a two-track data fetching strategy within the context provider:
-
Track 1 (Reactive): Use
K8s.ResourceClasses.Node.useList()andK8s.ResourceClasses.Pod.useList({namespace:''})for standard resources. These are reactive to cluster changes and automatically update when resources are created, modified, or deleted. -
Track 2 (Imperative): Use
ApiProxy.request()inside auseEffectkeyed onrefreshKeyfor GpuDevicePlugin CRDs and DaemonSet pods. TherefreshKeyis incremented by therefresh()function exposed through the context.
Consequences
- ✅ Leverages Headlamp's reactive hooks for standard resources with automatic updates
- ✅ Flexible
ApiProxyfor custom CRDs without needing to register custom resource classes - ✅ Refresh mechanism provides manual control over imperative fetches
- ✅ Clean separation of reactive vs imperative data sources
- ⚠️ Two different update mechanisms (hooks auto-update vs manual refresh for CRDs)
- ⚠️ CRD data may lag behind hook data between refreshes
The negative consequences are mitigated by providing a manual refresh button in the UI, allowing users to force an update of imperative data when needed.
Alternatives Considered
-
All ApiProxy (no hooks) — Rejected. Loses reactivity for standard resources, meaning Node and Pod changes would not be reflected until a manual refresh.
-
All hooks (register CRD as custom resource class) — Rejected. Headlamp's
KubeObjectregistration is complex for read-only CRD access and would add unnecessary coupling to Headlamp internals. -
Single useEffect for everything — Rejected. Loses the reactivity benefit for Nodes and Pods, and would require manual refresh for all data instead of just CRDs.
Changelog
| Date | Change |
|---|---|
| 2026-03-05 | Initial decision accepted |