-
Type:
Problem report
-
Resolution: Unresolved
-
Priority:
Trivial
-
None
-
Affects Version/s: 7.4.14, 8.0.0beta2
-
Component/s: Frontend (F)
-
None
Steps to reproduce:
- Create a dashboard with an Item navigator widget and gauge widget whose Item is set to an itemnavigator or hostnavigator - whichever to makes the gauge listen to navigators broadcast.
- Pick two items with visibly different units/thresholds
- Throttle the network in DevTools, or make sure to choose an item whose widget.gauge.view request is slow to load/render.
- Click item A in the navigator. While the Gauge request for A is still pending, click item B
Result:
Gauge briefly renders item A's response, then re-fetches and shows item B's value - but with item A's config (units, thresholds, min/max). The corrective request was sent with with_config imitted, so the server returned only the value and the client kept the previous config.
The same pattern affects other listeners, like the map (sysmapid change during an in-flight update does not reset the map navigation history), graph, svggraph, scatter plot (time_period change), and the navigators, honeycomb, problems, tophosts, etc (selection is not reset after inputs change).
Additionally, the request that was in flight when the second click happened is not aborted - it runs to completion. It response is rendered, and only then - after up to a further 1s poll delay - is the correct request sent.
Expected:
When the new referred data arrives while a widget update is in flight, the stale request should be aborted and the next update cycle should observe isFieldsReferredDataUpdated() === true for the changed paths, so widgets that branch on it (with_config, selection reset, time_period rebroadcast, etc.) take the "referred data changed" path.
Analysis:
In ui/class.widget-base.js, _update():
- #fields_referred_data_updated is populated by the broadcast subscription callback and cleared inside the success .then() of promiseUpdate(). If a broadcast arrives between request dispatch and response, its mark is wiped that .clear() even though the just-rendered response does not reflect it. The 1 second deferred retry then dispatches a request whose body carries the new referred value (via getFieldsData()), but every isFieldsReferredDataUpdate() call inside that cycle returns false.
- The broadcast subscription callback calls _startUpdating() but does not abort _update_abort_controller, so the stale request keeps running and its response is rendered before being replaced.
Suggested Fix:
Split the state into "pending since last dispatch" and "carried by the in-flight request":
- On dispatch, move #fields_referred_data_updated into a new #fields_referred_data_dispatched and start a fresh updated set.
- isFieldsReferredDataUpdated() returns the union, so widget subclasses see the correct answer during promiseUpdate() processUpdateResponse().
- On success, clear on dispatched; updated retains any mid-flight broadcasts so the next cycle sees them.
- On error/abort, merge dispatched back into updated.
- In the broadcast subscription callback, abort the in-flight request before _startUpdating().