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]

Reply via email to