fix(epg): close source reconciliation review races

This commit is contained in:
4gray committed 2026-09-05 22:37:11 +02:00
1 parent ffcbee8140
commit e799fcec32
17 files changed
+396 -41

No files matched your search

+5 -2
View File
@@ -1331,7 +1331,9 @@ not global XMLTV owners. No source-discovery or provider matching policy changes
Reconciliation finds old sources in both XMLTV tables and queued imports. It
retires their generations before waiting for workers to exit, then uses the
existing source-clear worker. Programmes are deleted by source; a globally keyed
existing source-clear worker. Successfully cleared request candidates are forgotten
without resetting their generation fences; failed cleanups remain retryable.
Retired queued imports emit cancellation so progress rows disappear. Programmes are deleted by source; a globally keyed
channel is retained while another source still has programmes, transferring its
legacy owner to that remaining source. Manual mappings are preserved and can
resolve another retained source sharing that channel ID. Legacy programmes with
@@ -1341,7 +1343,8 @@ There is no new schema migration.
Renderer reconciliation increments a data revision and cancels earlier lookup
subscriptions, clears program caches and the selected M3U guide, and refreshes
Xtream selection and visible channel previews. A delayed startup import is
Xtream selection and visible channel previews, plus Stalker manual mapping
overrides and bulk guides. A delayed startup import is
started only if its source still belongs to the reconciled configuration; its
completion observer is installed after settings initialization. Provider EPG
continues through its existing APIs. Playlist refresh is not EPG cache cleanup.
+17 -13
View File
@@ -24,13 +24,13 @@ Stalker now uses two EPG paths with different purposes:
settled bulk guide cannot answer fall back to throttled per-channel
`get_short_epg` through `StalkerEpgPreviewQueue` (see "Channel row preview
flow").
- Effect ordering matters: the eager-EPG effect is registered **after** the
playlist-change effect that calls `clearBulkItvEpgCache()`. On a portal
switch the cache is cleared first and then refilled; if the order is
reversed the clear clobbers the just-loaded bulk EPG on initial render.
- `ensureBulkItvEpg` de-duplicates (via `isLoadingBulkItvEpg` /
`bulkItvEpgLoaded` + matching playlist/period), so the eager trigger and the
play-time `loadEpgForChannel` path never double-fetch.
- Effect ordering matters: the eager-EPG effect is registered **after** the
playlist-change effect that calls `clearBulkItvEpgCache()`. On a portal
switch the cache is cleared first and then refilled; if the order is
reversed the clear clobbers the just-loaded bulk EPG on initial render.
- `ensureBulkItvEpg` de-duplicates (via `isLoadingBulkItvEpg` /
`bulkItvEpgLoaded` + matching playlist/period), so the eager trigger and the
play-time `loadEpgForChannel` path never double-fetch.
- If a portal does not return usable bulk data for the selected channel, the
active panel falls back to `get_short_epg`.
@@ -196,12 +196,12 @@ Normalization rules:
### Key files
| File | Purpose |
| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `libs/portal/stalker/data-access/src/lib/stores/features/with-stalker-epg.feature.ts` | bulk cache and fallback handling |
| `libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` | active-channel EPG loading and controlled `app-epg-timeline` wiring |
| `libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.html` | active panel template |
| `libs/ui/epg/src/lib/epg-timeline/epg-timeline.component.ts` | shared controlled EPG timeline with date navigator |
| File | Purpose |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `libs/portal/stalker/data-access/src/lib/stores/features/with-stalker-epg.feature.ts` | bulk cache and fallback handling |
| `libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` | active-channel EPG loading and controlled `app-epg-timeline` wiring |
| `libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.html` | active panel template |
| `libs/ui/epg/src/lib/epg-timeline/epg-timeline.component.ts` | shared controlled EPG timeline with date navigator |
### Store API
@@ -283,6 +283,10 @@ rows stop consuming portal request capacity.
- Bulk EPG is fetched once per playlist session
- Channel switches only read from `bulkItvEpgByChannel`
- The cache is cleared when the Stalker playlist changes
- Committed XMLTV source reconciliation also clears mapping overrides, checked
IDs and bulk data, reloads the guide and selected mapping, and fences pending
mapping/bulk replies. Saved mappings remain authoritative even when removal
leaves their guide empty; portal EPG is not mixed into that empty override.
- This implementation does not add TTL-based refresh or background polling
## Authentication