fix(plex-sync): improve plex sync error handling. add session id to fix stuck runs

pull/638/head
sct 4 years ago
parent a7cc7c5975
commit a740b07f06

@ -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;
}
} }
} }

Loading…
Cancel
Save