eugenegujing opened a new pull request, #8854: URL: https://github.com/apache/texera/pull/8854
### What changes were proposed in this PR? `ComputingUnitStatusService` keeps the computing-unit list and the selected unit's status fresh through two RxJS pipelines: the list refresh (`refreshComputingUnitListSignal → switchMap(listComputingUnits) → subscribe`) and the selected-unit poll (`interval(2000) → switchMap(getComputingUnit) → subscribe`). Neither inner HTTP observable had any error handling. In RxJS an error is a terminal notification: `switchMap` forwards an inner error downstream unchanged, and a subscriber that receives it is closed for good. Both subscriptions are created once, in the constructor of this root-provided service, and nothing ever re-creates them. So a single failed request (a 500, a 502/504 from the proxy while the computing-unit managing service restarts, a network blip) killed the pipeline for the rest of the page's life. The refresh signal kept being pushed every second by the dashboard, into a `Subject` with no subscriber left. The only trace was one `ERROR HttpErrorResponse` in the console; the UI showed nothing. What users saw until they reloaded the page: - the dashboard's Computing Units list froze: units created elsewhere never appeared, terminated ones never disappeared; - the workspace's computing-unit dropdown stopped refreshing; - the selected unit's status never changed again, so the Failed / Terminating states from #7944 could not reach the UI; - the canvas run button could stay on "Connecting" after the socket was actually up, because its state is recomputed on poll emissions. **The change** wraps the inner HTTP observable of both `switchMap`s in `catchError(() => EMPTY)`. A failed fetch now completes without emitting, which `switchMap` treats as "this round is over, wait for the next signal"; the stream stays subscribed and the next refresh signal or poll tick fetches again. `EMPTY` rather than an empty list keeps the cached list and the selected unit untouched during the failed round, so nothing flickers. A failed fetch is swallowed without logging, matching the other periodic poll in the frontend (`agent.service.ts`, `retrieveWorkflow` every second with `catchError(() => of(null))`); the failed requests remain visible in the browser's Network panel. Eight lines in the service, nothing else changes. #### Before: one failed request freezes the dashboard The black panel in the top-right corner is a debugging overlay injected into the page for the reproduction (it counts `GET api/computing-unit` requests and can make exactly one of them fail); it is not part of Texera. Normal state: the dashboard requests the list once a second. <img width="1568" height="562" alt="bug1-01-normal-list-refreshing-every-second" src="https://github.com/user-attachments/assets/ab652efb-eebe-47a2-9d25-d136733275eb" /> One request is made to fail. Eight seconds later no further request has been sent, although the page still asks for a refresh every second. <img width="1568" height="562" alt="bug1-02-one-injected-failure-no-requests-for-8s" src="https://github.com/user-attachments/assets/9ae568da-292c-405f-b419-f8fc2fa9ae04" /> From a second tab, a computing unit is terminated; that tab shows one unit immediately. <img width="1568" height="562" alt="bug1-03-other-tab-unit-4-removed-shows-1-unit" src="https://github.com/user-attachments/assets/dececa82-2f90-4131-a933-d80b0b42e33c" /> 87 seconds after the failure the first tab still shows two units and has sent no request. Reloading the page restores the list at once, so the backend was healthy the whole time. <img width="1568" height="562" alt="bug1-04-this-tab-frozen-87s-still-shows-2-units-BUG" src="https://github.com/user-attachments/assets/fe9b6f68-f54e-4ab0-baf0-ae208a41d56b" /> #### After: the same failure, on this branch Same page, same overlay, served from this branch. One request (45) is made to fail; eight seconds later eight more requests have gone out and the list is still refreshing. <img width="1568" height="562" alt="fixed-bug1-02-one-injected-failure-requests-keep-flowing-8-since" src="https://github.com/user-attachments/assets/d9c8efe1-f014-488f-abfe-8f02027002da" /> A unit created from a second tab appears on this page within a second (78 requests since the failure), and disappears again when it is terminated from the other tab (138 requests since the failure), all without a reload. <img width="1568" height="562" alt="fixed-bug1-03-unit-created-in-other-tab-appears-here" src="https://github.com/user-attachments/assets/775fc80e-7b3e-487c-8fab-8df660d4fbcd" /> <img width="1568" height="562" alt="fixed-bug1-04-unit-removed-in-other-tab-disappears-here-138-since-fail" src="https://github.com/user-attachments/assets/4dd8495c-fc35-40c3-9a67-c4d9ca899d6a" /> ### Any related issues, documentation, discussions? Closes #8850 Related follow-ups that depend on this fix landing first (not part of this PR): a selected unit whose pod vanishes polls back to Pending forever, and dropdown rows do not refresh while the dropdown is open. Both of their fixes call `refreshComputingUnitList()`, which only works if this pipeline is alive. ### How was this PR tested? - **New unit tests** in `computing-unit-status.service.spec.ts` (all red before the fix): the list keeps refreshing after one failed fetch and through several consecutive failures; a failed fetch emits nothing and the next success emits the good list; the selected-unit poll keeps polling after one failed fetch, leaves the selection object untouched and the poll subscription open. - **Mutation check**, each mutation restored afterwards: removing the `catchError` from either pipeline, moving it outside the `switchMap`, or replacing `EMPTY` with `of([])` / `of(null)` each turns at least one of the new tests red. - **Spec file**: 35 passed. **Full frontend suite** (`ng test --watch=false`): 231 files, 6448 passed, 1 skipped (pre-existing), 0 failed. `prettier --check` clean on both files. - **Bug reproduced in a running local instance** (screenshots above): Chrome against the Angular dev server and the local computing-unit managing service, with a page-level `XMLHttpRequest` wrapper that fails exactly one list request. Reproducible without instrumentation by stopping the computing-unit managing service for a few seconds while the dashboard's Compute page is open, starting it again, and changing a unit from another tab. - **Fixed build exercised in the same local instance** (screenshots in the "After" section): after one injected failure the request counter kept increasing once a second (138 requests over the following two minutes), a unit created from another tab appeared within a second, and the same unit disappeared within a second after being terminated from the other tab. No reload. ### Was this PR authored or co-authored using generative AI tooling? Yes. Generated-by: Claude Code (claude-fable-5-1). Co-authored with Claude; the author reviewed the change before submission. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
