chore(tmdb): use mutex to avoid double tmdb requests
This commit is contained in:
parent
3b8481ed3f
commit
e1b5e7bce1
2 changed files with 72 additions and 41 deletions
|
|
@ -8,33 +8,40 @@ const ctx = createTestContext();
|
|||
|
||||
describe('getTmdbIdFromImdbId', () => {
|
||||
test('series', async () => {
|
||||
const tmdbId1 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4));
|
||||
expect(tmdbId1).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId1).toHaveProperty('id', 42009);
|
||||
expect(tmdbId1).toHaveProperty('season', 2);
|
||||
expect(tmdbId1).toHaveProperty('episode', 4);
|
||||
const results = await Promise.all([
|
||||
getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4)),
|
||||
getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4)),
|
||||
]);
|
||||
expect(results[0]).toBeInstanceOf(TmdbId);
|
||||
expect(results[0]).toHaveProperty('id', 42009);
|
||||
expect(results[0]).toHaveProperty('season', 2);
|
||||
expect(results[0]).toHaveProperty('episode', 4);
|
||||
|
||||
// from cache
|
||||
const tmdbId2 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4));
|
||||
expect(tmdbId2).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId2).toHaveProperty('id', 42009);
|
||||
expect(tmdbId2).toHaveProperty('season', 2);
|
||||
expect(tmdbId2).toHaveProperty('episode', 4);
|
||||
const tmdbId = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4));
|
||||
expect(tmdbId).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId).toHaveProperty('id', 42009);
|
||||
expect(tmdbId).toHaveProperty('season', 2);
|
||||
expect(tmdbId).toHaveProperty('episode', 4);
|
||||
});
|
||||
|
||||
test('movie', async () => {
|
||||
const tmdbId1 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined));
|
||||
expect(tmdbId1).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId1).toHaveProperty('id', 931944);
|
||||
expect(tmdbId1).toHaveProperty('season', undefined);
|
||||
expect(tmdbId1).toHaveProperty('episode', undefined);
|
||||
const results = await Promise.all([
|
||||
getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined)),
|
||||
getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined)),
|
||||
]);
|
||||
|
||||
expect(results[0]).toBeInstanceOf(TmdbId);
|
||||
expect(results[0]).toHaveProperty('id', 931944);
|
||||
expect(results[0]).toHaveProperty('season', undefined);
|
||||
expect(results[0]).toHaveProperty('episode', undefined);
|
||||
|
||||
// from cache
|
||||
const tmdbId2 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined));
|
||||
expect(tmdbId2).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId2).toHaveProperty('id', 931944);
|
||||
expect(tmdbId2).toHaveProperty('season', undefined);
|
||||
expect(tmdbId2).toHaveProperty('episode', undefined);
|
||||
const tmdbId = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined));
|
||||
expect(tmdbId).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId).toHaveProperty('id', 931944);
|
||||
expect(tmdbId).toHaveProperty('season', undefined);
|
||||
expect(tmdbId).toHaveProperty('episode', undefined);
|
||||
});
|
||||
|
||||
test('throws with invalid imdb id', async () => {
|
||||
|
|
@ -44,33 +51,41 @@ describe('getTmdbIdFromImdbId', () => {
|
|||
|
||||
describe('getImdbIdFromTmdbId', () => {
|
||||
test('series', async () => {
|
||||
const imdbId1 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4));
|
||||
expect(imdbId1).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId1).toHaveProperty('id', 'tt2085059');
|
||||
expect(imdbId1).toHaveProperty('season', 2);
|
||||
expect(imdbId1).toHaveProperty('episode', 4);
|
||||
const results = await Promise.all([
|
||||
getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4)),
|
||||
getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4)),
|
||||
]);
|
||||
|
||||
expect(results[0]).toBeInstanceOf(ImdbId);
|
||||
expect(results[0]).toHaveProperty('id', 'tt2085059');
|
||||
expect(results[0]).toHaveProperty('season', 2);
|
||||
expect(results[0]).toHaveProperty('episode', 4);
|
||||
|
||||
// from cache
|
||||
const imdbId2 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4));
|
||||
expect(imdbId2).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId2).toHaveProperty('id', 'tt2085059');
|
||||
expect(imdbId2).toHaveProperty('season', 2);
|
||||
expect(imdbId2).toHaveProperty('episode', 4);
|
||||
const imdbId = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4));
|
||||
expect(imdbId).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId).toHaveProperty('id', 'tt2085059');
|
||||
expect(imdbId).toHaveProperty('season', 2);
|
||||
expect(imdbId).toHaveProperty('episode', 4);
|
||||
});
|
||||
|
||||
test('movie', async () => {
|
||||
const imdbId1 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined));
|
||||
expect(imdbId1).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId1).toHaveProperty('id', 'tt29141112');
|
||||
expect(imdbId1).toHaveProperty('season', undefined);
|
||||
expect(imdbId1).toHaveProperty('episode', undefined);
|
||||
const results = await Promise.all([
|
||||
getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined)),
|
||||
getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined)),
|
||||
]);
|
||||
|
||||
expect(results[0]).toBeInstanceOf(ImdbId);
|
||||
expect(results[0]).toHaveProperty('id', 'tt29141112');
|
||||
expect(results[0]).toHaveProperty('season', undefined);
|
||||
expect(results[0]).toHaveProperty('episode', undefined);
|
||||
|
||||
// from cache
|
||||
const imdbId2 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined));
|
||||
expect(imdbId2).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId2).toHaveProperty('id', 'tt29141112');
|
||||
expect(imdbId2).toHaveProperty('season', undefined);
|
||||
expect(imdbId2).toHaveProperty('episode', undefined);
|
||||
const imdbId = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined));
|
||||
expect(imdbId).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId).toHaveProperty('id', 'tt29141112');
|
||||
expect(imdbId).toHaveProperty('season', undefined);
|
||||
expect(imdbId).toHaveProperty('episode', undefined);
|
||||
});
|
||||
|
||||
test('throws with invalid tmdb id', async () => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Mutex } from 'async-mutex';
|
||||
import { NotFoundError } from '../error';
|
||||
import { Context } from '../types';
|
||||
import { envGet } from './env';
|
||||
|
|
@ -27,6 +28,7 @@ interface TvDetailsResponsePartial {
|
|||
name: string;
|
||||
}
|
||||
|
||||
const mutexes = new Map<string, Mutex>();
|
||||
const tmdbFetch = async (ctx: Context, fetcher: Fetcher, path: string, searchParams?: Record<string, string | undefined>): Promise<unknown> => {
|
||||
const config: CustomRequestInit = {
|
||||
headers: {
|
||||
|
|
@ -44,7 +46,21 @@ const tmdbFetch = async (ctx: Context, fetcher: Fetcher, path: string, searchPar
|
|||
}
|
||||
});
|
||||
|
||||
return JSON.parse(await fetcher.text(ctx, url, config));
|
||||
let mutex = mutexes.get(url.href);
|
||||
if (!mutex) {
|
||||
mutex = new Mutex();
|
||||
mutexes.set(url.href, mutex);
|
||||
}
|
||||
|
||||
const data = await mutex.runExclusive(async () => {
|
||||
return JSON.parse(await fetcher.text(ctx, url, config));
|
||||
});
|
||||
|
||||
if (!mutex.isLocked()) {
|
||||
mutexes.delete(url.href);
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
const imdbTmdbMap = new Map<string, number>();
|
||||
|
|
|
|||
Loading…
Reference in a new issue