Infinite route-loader spinner: per-navigation invalidateRootCache() deadlocks getEndpointMapAt when the root endpoint goes stale
Maintainer thường phản hồi trong vòng 1 ngày
@naomigassler đang làm issue này rồi.
Từ ngày 9/7/2026.
- #5936 của @naomigassler — đã đóng, không merge
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Describe the bug
After the UI has been open a while, navigating to / revisiting a page can leave the app stuck on the route-loader spinner (<ds-loading> in ds-base-root, driven by AppComponent.isRouteLoading$) forever. The shell stays responsive (navbar, sidebar, overlays work); a full reload or clicking any other in-app link recovers it, but the routed content never renders. While stuck: nothing is pending on the network, the NgRx store is frozen, and CPU/memory are idle — a logical deadlock, not a loop or leak. It is much harder to reproduce with DevTools open and far worse in production than on a local dev server (cf. #3584, #3697).
To Reproduce
Authenticated, ideally behind a reverse proxy / with non-trivial REST latency:
- Load a content page (e.g. a Community/Collection).
- Navigate around / wait a bit.
- Navigate back (or keep navigating). The spinner appears and never resolves; reload or any other link recovers it. Higher REST latency → more reliable (essentially every revisit through a proxy).
Expected behavior
Navigation completes and the page renders; a transiently-stale root endpoint must not wedge navigation indefinitely.
Root cause
BrowserInitService.listenForRouteChanges()callsrootDataService.invalidateRootCache()on everyNavigationStart→RequestService.setStaleByHref('/server/api')marks the root request stale (regardless of its TTL).HALEndpointService.getEndpointMapAt()— used bygetEndpoint(), which every data request needs — doesfilter(rd => !rd.isStale), discarding the stale root; itstap(... getEndpointMapAt())re-request does not reliably produce a fresh one, so it never emits.- So
getEndpoint()never resolves → the route resolver never completes → the router never emitsNavigationEnd→isRouteLoading$(cleared only onNavigationEnd/Cancel) staystrue→ the route loader spins forever, store frozen.
Evidence (frozen store at the hang): root /server/api is SuccessStale with TTL not expired (explicitly invalidated, not aged out); 0 requests pending (nothing re-fetching); the only RequestStaleAction caller is setStaleByHref ← invalidateRootCache ← the NavigationStart subscription. Consistent with #2669 (invalidateRootCache ↔ HALEndpointService stale interaction) after #2510 (7.6.1) made HAL endpoint requests stale-able.
Proposed fix
The root endpoint map is static between navigations, so the per-NavigationStart invalidation is unnecessary. Removing it eliminates the deadlock (backend availability is still established at app init and surfaces through normal request failures):
import {
- NavigationStart,
Router,
} from '@angular/router';
@@ listenForRouteChanges()
protected listenForRouteChanges(): void {
- // we'll always be too late for the first NavigationStart event with the router subscribe below,
- // so this statement is for the very first route operation.
+ // Invalidate the root endpoint cache once, for the very first route operation.
this.rootDataService.invalidateRootCache();
-
- this.router.events.pipe(
- filter(event => event instanceof NavigationStart),
- ).subscribe(() => {
- this.rootDataService.invalidateRootCache();
- });
}
(Alternative, if the per-navigation backend check is to be kept: make getEndpointMapAt tolerate a stale-but-completed root, e.g. filter(rd => !rd.isStale || rd.hasCompleted), so a stale endpoint map is used while the tap() refreshes it — fixing the deadlock without changing the invalidation cadence.)
Verified: the change removes the hang and the E2E suite is unaffected.
Environment
- dspace-angular 9.3 (Angular 20.3);
listenForRouteChanges()/getEndpointMapAt()are unchanged onmainas of this report. - DSpace 9.3 REST backend behind an nginx reverse proxy; CSR (SSR disabled); reproduced in Safari and Firefox.
Related
#2669, #2510, #3584, #3697, #3888
- Ngôn ngữ chính
- TypeScript
- Star
- 180
- Fork
- 577
- Merge trung bình
- 2 ngày 1 giờ
- Pull request đã merge (30 ngày)
- 100
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của DSpace/dspace-angular
-
accessibility affects: 10.x affects: main bug ux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
DSpace/dspace-angular#6531 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
accessibility affects: 10.x affects: main bug help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
DSpace/dspace-angular#6530 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Submission Form Allows Deletion of All Repeating Item EntriesCó thể đã có người làm @Rowan-McKereghan đã nhận 5 ngày trước. Đang mởaffects: 8.x affects: 9.x bug component: submission
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
DSpace/dspace-angular#6511 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Visual issues with qualdrop fieldsCó thể đã có người làm @DanGastardelli đã nhận 15 ngày trước. Đang mởaffects: 10.x affects: 9.x bug claimed: Acervos Digitais component: submission Difficulty: Low ux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
DSpace/dspace-angular#6412 · 3 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Facet headings have incorrect clickable area to expand/collapseCó thể đã có người làm @jesielviana đã nhận 12 ngày trước. Đang mởaccessibility affects: 10.x affects: 8.x affects: 9.x bug ux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
DSpace/dspace-angular#6364 · 3 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của DSpace/dspace-angular
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
steelbrain/node-ssh#487 ·
-
cli: `execCargoMetadata` decodes stdout per chunk, corrupting non-ASCII paths across pipe boundariesĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 62/100
lingdojo/kana-dojo#34127 · 1 bình luận · 5 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 68/100
osmlab/name-suggestion-index#13104 ·
Maintainer thường phản hồi trong vòng 1 ngày