Summary
When a dynamic plugin's route/nav-item visibility is gated by a console.flag (or console.flag/hookProvider) whose value depends on an async check (e.g. probing a backend endpoint), the flag itself can resolve to true almost immediately, but the newly-enabled route/nav item does not actually become usable until up to ~10-15 seconds later. Until then, navigating directly to the flag-gated route 404s, and the flag-gated nav items are simply missing from the left nav. No console errors, no failed network requests, and no user-visible activity occur during this gap — it just "sits" until it silently self-corrects.
This was observed with a dev build of openshift-servicemesh-plugin (OSSM Console / "ossmconsole") that is under construction, on OpenShift Console 4.22.8, but the mechanism appears to be generic to Console's flag/plugin-manifest handling and not specific to that plugin.
Repro steps
- Install a dynamic plugin that registers a
console.flag (or console.flag/hookProvider) extension whose handler performs an async check (e.g. fetch/consoleFetch to a backend endpoint) before calling setFeatureFlag(FLAG, true).
- Gate a
console.page/route and a console.navigation/href (or similar) extension on that flag.
- Load the Console. On first load, before the flag resolves, the route 404s and the nav item is absent (expected — the flag hasn't resolved yet).
- Confirm via network trace that the flag's own backend probe completes successfully (200 OK) within well under a second.
- Observe that the 404 page and the missing nav item persist for several more seconds after the flag has resolved to
true, then the correct page/nav item appears with no user action.
Evidence (Chrome DevTools Performance trace)
Captured a full Performance trace across the affected window and correlated Network, TimerInstall/TimerFire, and JS stack-trace data:
| Event |
Relative time |
Delta |
Plugin's flag-hookProvider chunk loads, calls its backend probe (GET .../kiali/api/status) |
t+0 ms |
— |
Probe responds 200 OK — flag resolves to true |
t+345 ms |
fast, correct |
A recurring timer (setInterval, 10000ms) is installed from Console's own main-bundle.min.js, essentially concurrently with the flag's probe |
t≈-3 ms |
(installed just before the flag resolved) |
| (nothing else happens — no network activity, no console output) |
|
|
| That timer fires for the first time |
t+9,997 ms |
~9.65 s after the flag resolved |
Console fetches plugin-manifest.json for every currently-enabled plugin at once (in this trace: monitoring-plugin, networking-console-plugin, and the plugin under test), all within ~1.4 ms of each other |
t+11,303 ms |
1.3 s after the timer fired |
| The flag-gated route's JS chunks load and the correct page renders |
shortly after |
|
Total measured delay from the flag resolving to the page rendering correctly: ~11 seconds, closely matching the "~10 seconds" reported by the person who first noticed this. This reproduces consistently.
I could not identify the exact named function that owns this specific 10-second interval, since main-bundle.min.js is minified in production and no source map was available in this session — but the timer is unambiguously installed and fired from Console's core bundle, not from the plugin under test, and its firing is followed immediately (1.3s later) by the batch plugin-manifest refetch that unblocks the page. I did check PollConsoleUpdates (frontend/public/components/poll-console-updates.tsx), which has a structurally similar behavior (batch-refetches every enabled plugin's plugin-manifest.json on every tick), but its usePoll interval is URL_POLL_DEFAULT_DELAY = 15000ms, not 10000ms, and its first tick fires immediately on mount rather than after a delay — so it doesn't line up with the observed 10000ms/~9.65s-until-first-fire timer, though it may be a related or duplicate mechanism worth checking with source maps attached.
Impact
Any dynamic plugin whose feature flag depends on an async check (which is the officially recommended console.flag/hookProvider pattern for exactly this case) will show a confusing 404 / missing-nav-item window of up to ~10-15 seconds after install or after the backend becomes reachable, with zero indication to the user of what's happening or when it will resolve. This makes async, backend-dependent feature flags effectively unusable for a good first-run experience, even though the flag mechanism itself works correctly and quickly.
Suggested fix direction
Whatever internal poll/timer is responsible for refreshing plugin manifests and/or re-evaluating flag-gated extensions after a flag changes value should react to the flag change directly (e.g. via the existing Redux flag state) rather than (or in addition to) waiting for the next tick of a fixed-interval background poll. At minimum, the poll interval could be shortened, or a flag-change event could trigger an immediate out-of-band tick instead of waiting for the next scheduled one.
Environment
- OpenShift Console version: 4.22.8
- Plugin:
openshift-servicemesh-plugin (ossmconsole), using console.flag/hookProvider for its KIALI_AVAILABLE flag
Summary
When a dynamic plugin's route/nav-item visibility is gated by a
console.flag(orconsole.flag/hookProvider) whose value depends on an async check (e.g. probing a backend endpoint), the flag itself can resolve totruealmost immediately, but the newly-enabled route/nav item does not actually become usable until up to ~10-15 seconds later. Until then, navigating directly to the flag-gated route 404s, and the flag-gated nav items are simply missing from the left nav. No console errors, no failed network requests, and no user-visible activity occur during this gap — it just "sits" until it silently self-corrects.This was observed with a dev build of
openshift-servicemesh-plugin(OSSM Console / "ossmconsole") that is under construction, on OpenShift Console 4.22.8, but the mechanism appears to be generic to Console's flag/plugin-manifest handling and not specific to that plugin.Repro steps
console.flag(orconsole.flag/hookProvider) extension whose handler performs an async check (e.g.fetch/consoleFetchto a backend endpoint) before callingsetFeatureFlag(FLAG, true).console.page/routeand aconsole.navigation/href(or similar) extension on that flag.true, then the correct page/nav item appears with no user action.Evidence (Chrome DevTools Performance trace)
Captured a full Performance trace across the affected window and correlated
Network,TimerInstall/TimerFire, and JS stack-trace data:GET .../kiali/api/status)truesetInterval, 10000ms) is installed from Console's ownmain-bundle.min.js, essentially concurrently with the flag's probeplugin-manifest.jsonfor every currently-enabled plugin at once (in this trace:monitoring-plugin,networking-console-plugin, and the plugin under test), all within ~1.4 ms of each otherTotal measured delay from the flag resolving to the page rendering correctly: ~11 seconds, closely matching the "~10 seconds" reported by the person who first noticed this. This reproduces consistently.
I could not identify the exact named function that owns this specific 10-second interval, since
main-bundle.min.jsis minified in production and no source map was available in this session — but the timer is unambiguously installed and fired from Console's core bundle, not from the plugin under test, and its firing is followed immediately (1.3s later) by the batch plugin-manifest refetch that unblocks the page. I did checkPollConsoleUpdates(frontend/public/components/poll-console-updates.tsx), which has a structurally similar behavior (batch-refetches every enabled plugin'splugin-manifest.jsonon every tick), but itsusePollinterval isURL_POLL_DEFAULT_DELAY= 15000ms, not 10000ms, and its first tick fires immediately on mount rather than after a delay — so it doesn't line up with the observed 10000ms/~9.65s-until-first-fire timer, though it may be a related or duplicate mechanism worth checking with source maps attached.Impact
Any dynamic plugin whose feature flag depends on an async check (which is the officially recommended
console.flag/hookProviderpattern for exactly this case) will show a confusing 404 / missing-nav-item window of up to ~10-15 seconds after install or after the backend becomes reachable, with zero indication to the user of what's happening or when it will resolve. This makes async, backend-dependent feature flags effectively unusable for a good first-run experience, even though the flag mechanism itself works correctly and quickly.Suggested fix direction
Whatever internal poll/timer is responsible for refreshing plugin manifests and/or re-evaluating flag-gated extensions after a flag changes value should react to the flag change directly (e.g. via the existing Redux flag state) rather than (or in addition to) waiting for the next tick of a fixed-interval background poll. At minimum, the poll interval could be shortened, or a flag-change event could trigger an immediate out-of-band tick instead of waiting for the next scheduled one.
Environment
openshift-servicemesh-plugin(ossmconsole), usingconsole.flag/hookProviderfor itsKIALI_AVAILABLEflag