mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-10 03:50:52 +00:00
dedup fix localscraper
This commit is contained in:
parent
028c6d2823
commit
c358c794ec
1 changed files with 35 additions and 12 deletions
|
|
@ -81,6 +81,8 @@ class LocalScraperService {
|
||||||
private autoRefreshCompleted: boolean = false;
|
private autoRefreshCompleted: boolean = false;
|
||||||
private isRefreshing: boolean = false;
|
private isRefreshing: boolean = false;
|
||||||
private scraperSettingsCache: Record<string, any> | null = null;
|
private scraperSettingsCache: Record<string, any> | null = null;
|
||||||
|
// Single-flight map to prevent duplicate concurrent runs per scraper+title
|
||||||
|
private inFlightByKey: Map<string, Promise<LocalScraperResult[]>> = new Map();
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
|
@ -877,9 +879,12 @@ class LocalScraperService {
|
||||||
|
|
||||||
logger.log('[LocalScraperService] Executing', enabledScrapers.length, 'scrapers for', type, tmdbId);
|
logger.log('[LocalScraperService] Executing', enabledScrapers.length, 'scrapers for', type, tmdbId);
|
||||||
|
|
||||||
|
// Generate a lightweight request id for tracing
|
||||||
|
const requestId = `rs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
||||||
|
|
||||||
// Execute each scraper
|
// Execute each scraper
|
||||||
for (const scraper of enabledScrapers) {
|
for (const scraper of enabledScrapers) {
|
||||||
this.executeScraper(scraper, type, tmdbId, season, episode, callback);
|
this.executeScraper(scraper, type, tmdbId, season, episode, callback, requestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -890,7 +895,8 @@ class LocalScraperService {
|
||||||
tmdbId: string,
|
tmdbId: string,
|
||||||
season?: number,
|
season?: number,
|
||||||
episode?: number,
|
episode?: number,
|
||||||
callback?: ScraperCallback
|
callback?: ScraperCallback,
|
||||||
|
requestId?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const code = this.scraperCode.get(scraper.id);
|
const code = this.scraperCode.get(scraper.id);
|
||||||
|
|
@ -903,15 +909,32 @@ class LocalScraperService {
|
||||||
// Load per-scraper settings
|
// Load per-scraper settings
|
||||||
const scraperSettings = await this.getScraperSettings(scraper.id);
|
const scraperSettings = await this.getScraperSettings(scraper.id);
|
||||||
|
|
||||||
// Create a sandboxed execution environment
|
// Build single-flight key
|
||||||
const results = await this.executeSandboxed(code, {
|
const flightKey = `${scraper.id}|${type}|${tmdbId}|${season ?? ''}|${episode ?? ''}`;
|
||||||
tmdbId,
|
|
||||||
mediaType: type,
|
// Create a sandboxed execution environment with single-flight coalescing
|
||||||
season,
|
let promise: Promise<LocalScraperResult[]>;
|
||||||
episode,
|
if (this.inFlightByKey.has(flightKey)) {
|
||||||
scraperId: scraper.id,
|
promise = this.inFlightByKey.get(flightKey)!;
|
||||||
settings: scraperSettings
|
} else {
|
||||||
});
|
promise = this.executeSandboxed(code, {
|
||||||
|
tmdbId,
|
||||||
|
mediaType: type,
|
||||||
|
season,
|
||||||
|
episode,
|
||||||
|
scraperId: scraper.id,
|
||||||
|
settings: scraperSettings,
|
||||||
|
requestId
|
||||||
|
});
|
||||||
|
this.inFlightByKey.set(flightKey, promise);
|
||||||
|
// Clean up after settle; guard against races
|
||||||
|
promise.finally(() => {
|
||||||
|
const current = this.inFlightByKey.get(flightKey);
|
||||||
|
if (current === promise) this.inFlightByKey.delete(flightKey);
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await promise;
|
||||||
|
|
||||||
// Convert results to Nuvio Stream format
|
// Convert results to Nuvio Stream format
|
||||||
const streams = this.convertToStreams(results, scraper);
|
const streams = this.convertToStreams(results, scraper);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue