mirror of
https://github.com/sct/overseerr.git
synced 2025-09-27 04:22:37 +02:00
fix(plex-sync): improve plex sync error handling. add session id to fix stuck runs
This commit is contained in:
@@ -11,6 +11,7 @@ import logger from '../../logger';
|
|||||||
import { getSettings, Library } from '../../lib/settings';
|
import { getSettings, Library } from '../../lib/settings';
|
||||||
import Season from '../../entity/Season';
|
import Season from '../../entity/Season';
|
||||||
import { uniqWith } from 'lodash';
|
import { uniqWith } from 'lodash';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
import animeList from '../../api/animelist';
|
import animeList from '../../api/animelist';
|
||||||
import AsyncLock from '../../utils/asyncLock';
|
import AsyncLock from '../../utils/asyncLock';
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ interface SyncStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JobPlexSync {
|
class JobPlexSync {
|
||||||
|
private sessionId: string;
|
||||||
private tmdb: TheMovieDb;
|
private tmdb: TheMovieDb;
|
||||||
private plexClient: PlexAPI;
|
private plexClient: PlexAPI;
|
||||||
private items: PlexLibraryItem[] = [];
|
private items: PlexLibraryItem[] = [];
|
||||||
@@ -608,22 +610,35 @@ class JobPlexSync {
|
|||||||
private async loop({
|
private async loop({
|
||||||
start = 0,
|
start = 0,
|
||||||
end = BUNDLE_SIZE,
|
end = BUNDLE_SIZE,
|
||||||
|
sessionId,
|
||||||
}: {
|
}: {
|
||||||
start?: number;
|
start?: number;
|
||||||
end?: number;
|
end?: number;
|
||||||
|
sessionId?: string;
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const slicedItems = this.items.slice(start, end);
|
const slicedItems = this.items.slice(start, end);
|
||||||
if (start < this.items.length && this.running) {
|
|
||||||
|
if (!this.running) {
|
||||||
|
throw new Error('Sync was aborted.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sessionId !== sessionId) {
|
||||||
|
throw new Error('New session was started. Old session aborted.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start < this.items.length) {
|
||||||
this.progress = start;
|
this.progress = start;
|
||||||
await this.processItems(slicedItems);
|
await this.processItems(slicedItems);
|
||||||
|
|
||||||
await new Promise<void>((resolve) =>
|
await new Promise<void>((resolve, reject) =>
|
||||||
setTimeout(async () => {
|
setTimeout(() => {
|
||||||
await this.loop({
|
this.loop({
|
||||||
start: start + BUNDLE_SIZE,
|
start: start + BUNDLE_SIZE,
|
||||||
end: end + BUNDLE_SIZE,
|
end: end + BUNDLE_SIZE,
|
||||||
});
|
sessionId,
|
||||||
resolve();
|
})
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch((e) => reject(new Error(e.message)));
|
||||||
}, UPDATE_RATE)
|
}, UPDATE_RATE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -650,7 +665,10 @@ class JobPlexSync {
|
|||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const settings = getSettings();
|
const settings = getSettings();
|
||||||
if (!this.running) {
|
const sessionId = uuid();
|
||||||
|
this.sessionId = sessionId;
|
||||||
|
logger.info('Plex Sync Starting', { sessionId, label: 'Plex Sync' });
|
||||||
|
try {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
const userRepository = getRepository(User);
|
const userRepository = getRepository(User);
|
||||||
const admin = await userRepository.findOne({
|
const admin = await userRepository.findOne({
|
||||||
@@ -671,7 +689,7 @@ class JobPlexSync {
|
|||||||
this.enable4kMovie = settings.radarr.some((radarr) => radarr.is4k);
|
this.enable4kMovie = settings.radarr.some((radarr) => radarr.is4k);
|
||||||
if (this.enable4kMovie) {
|
if (this.enable4kMovie) {
|
||||||
this.log(
|
this.log(
|
||||||
'At least one 4K Radarr server was detected, so 4K movie detection is now enabled',
|
'At least one 4K Radarr server was detected. 4K movie detection is now enabled',
|
||||||
'info'
|
'info'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -679,7 +697,7 @@ class JobPlexSync {
|
|||||||
this.enable4kShow = settings.sonarr.some((sonarr) => sonarr.is4k);
|
this.enable4kShow = settings.sonarr.some((sonarr) => sonarr.is4k);
|
||||||
if (this.enable4kShow) {
|
if (this.enable4kShow) {
|
||||||
this.log(
|
this.log(
|
||||||
'At least one 4K Sonarr server was detected, so 4K series detection is now enabled',
|
'At least one 4K Sonarr server was detected. 4K series detection is now enabled',
|
||||||
'info'
|
'info'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -715,18 +733,31 @@ class JobPlexSync {
|
|||||||
return mediaA.ratingKey === mediaB.ratingKey;
|
return mediaA.ratingKey === mediaB.ratingKey;
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.loop();
|
await this.loop({ sessionId });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const library of this.libraries) {
|
for (const library of this.libraries) {
|
||||||
this.currentLibrary = library;
|
this.currentLibrary = library;
|
||||||
this.log(`Beginning to process library: ${library.name}`, 'info');
|
this.log(`Beginning to process library: ${library.name}`, 'info');
|
||||||
this.items = await this.plexClient.getLibraryContents(library.id);
|
this.items = await this.plexClient.getLibraryContents(library.id);
|
||||||
await this.loop();
|
await this.loop({ sessionId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.running = false;
|
this.log(
|
||||||
this.log('complete');
|
this.isRecentOnly
|
||||||
|
? 'Recently Added Scan Complete'
|
||||||
|
: 'Full Scan Complete'
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Sync interrupted', {
|
||||||
|
label: 'Plex Sync',
|
||||||
|
errorMessage: e.message,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
// If a new scanning session hasnt started, set running back to false
|
||||||
|
if (this.sessionId === sessionId) {
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user