Cache full processed pipeline for faster response#1075
Conversation
…s, dashboard adapters)
The old nzbFailover.ts was nzb-only; this overhauls it into a generic failover chain (FailoverContentType = 'usenet' | 'debrid') that also handles debrid and supports parallel queuing / staggered races (parallel, staggerMs, preferredGraceMs, maxWaitMs).
…real-world codec aliases
…en applying to streams
…lity (Viren070#1070) Cloudflare classifies requests by the URL path extension alone: a stream URL ending in /<filename>.mkv is treated as a cacheable file type, so on every cache miss (guaranteed, as the route sends no-store) the proxy requests the entire file from origin and never forwards the client's Range header. Every seek then costs a full-file pull, playback stalls, and abandoned pulls pile up as orphaned full-file readers. Dropping the filename segment makes Cloudflare treat the response as dynamic and pass Range through verbatim. The route already accepts both forms, so previously minted URLs keep working; players still receive the real filename via Content-Disposition. Co-authored-by: Viren070 <viren070@protonmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds a ChangesStream result caching
Estimated code review effort: 2 (Simple) | ~12 minutes Sequence Diagram(s)sequenceDiagram
participant Route as stream.ts route
participant AIOStreams as AIOStreams.getStreams
participant Cache as Cache('pipeline-result')
participant Pipeline as _getStreams
Route->>AIOStreams: getStreams(type, id, userData)
AIOStreams->>Cache: get(cacheKey)
alt cache hit
Cache-->>AIOStreams: cached result
AIOStreams->>AIOStreams: recreate streamContext
AIOStreams-->>Route: cached result
else cache miss
AIOStreams->>Pipeline: _getStreams(type, id, userData)
Pipeline-->>AIOStreams: result
AIOStreams->>Cache: set(cacheKey, result, ttl)
AIOStreams-->>Route: result
end
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Viren070
left a comment
There was a problem hiding this comment.
the caching itself needs to be done in the AIOStreams class so all consumers of it benefit (e.g. search api route, torznab apis etc.).
why not use the existing Cache class ?
Lemme look into it. |
I think I addressed your feedback, please take a look now. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/core/src/main/index.ts (1)
88-124: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoffConcurrent requests for the same key will both miss and recompute (cache stampede).
Two simultaneous requests for the same
(uuid, type, id)before the cache is populated will both fall through to_getStreams, doing the full pipeline work twice. Since the pipeline is described as expensive (addon fetching, filtering, sorting), an in-flight request de-duplication (e.g., caching the in-flight promise) would improve the benefit of this cache under concurrent access such as page refresh bursts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/main/index.ts` around lines 88 - 124, The pipeline result cache in the _getStreams flow currently only stores completed values, so concurrent requests for the same cacheKey can both miss and run the expensive pipeline work twice. Update the cache logic around pipelineCache.get/set to deduplicate in-flight requests for the same (uuid, type, id), for example by storing the pending _getStreams promise or otherwise sharing a single execution until it resolves, while keeping the existing cache hit behavior and StreamContext.create reset on hits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/core/src/main/index.ts`:
- Around line 94-122: The cache-hit branch in index.ts only recreates
StreamContext with StreamContext.create(), but it misses formatter-relevant
state used by toFormatterContext() such as _metadata, _episodeDetails, and
_seadex. Update the pipeline-result cache flow so the cache key/result also
carries this formatter context, or rehydrate those fields on a cache hit using
the same data populated by startAllFetches() in _getStreams, ensuring cached and
non-cached paths produce equivalent formatting behavior.
---
Nitpick comments:
In `@packages/core/src/main/index.ts`:
- Around line 88-124: The pipeline result cache in the _getStreams flow
currently only stores completed values, so concurrent requests for the same
cacheKey can both miss and run the expensive pipeline work twice. Update the
cache logic around pipelineCache.get/set to deduplicate in-flight requests for
the same (uuid, type, id), for example by storing the pending _getStreams
promise or otherwise sharing a single execution until it resolves, while keeping
the existing cache hit behavior and StreamContext.create reset on hits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 716429fe-49e3-4c58-b28f-6aaaa9fb759f
📒 Files selected for processing (3)
packages/core/src/config/schema/resources.tspackages/core/src/main/index.tspackages/server/src/routes/stremio/stream.ts
Adds a configurable in-memory cache for the fully-processed Stremio stream response, so repeat requests for the same
(user, type, id)skip the entire pipeline. Off by defaultProblem
Every Stremio stream request runs the full pipeline — fetching manifests, service wrapping, deduplication, filtering, sorting, SEL evaluation, formatting, and proxying. Stremio frequently re-requests the same
(type, id)when users refresh, navigate back, or click between episodes, making this redundant.Solution
Cache the final
AIOStreamResponsein an in-memoryMap<string, CachedStreamResult>. Uses a dedicated Map rather than the genericCacheclass to avoidstructuredCloneoverhead on large stream arrays.{uuid}:{type}:{id}— per-user, per-media-itemSTREAM_RESULT_CACHE_TTL(default 30s, 0 = disabled)STREAM_RESULT_CACHE_MAX_SIZE(default 1000)Changes
packages/core/src/config/schema/resources.tscache.streamResultconfig section withttlandmaxSizepackages/server/src/routes/stremio/stream.tsConfiguration
STREAM_RESULT_CACHE_TTL0STREAM_RESULT_CACHE_MAX_SIZE1000Can be viewed/edited in dashboard:

This will be a stricter cache than the one used by STREAM_CACHE_TTL.
Summary by CodeRabbit
ttlandmaxSize, with environment variable support.