Prevent concurrent tracker calls during manga migration

This commit is contained in:
schroda
2026-05-13 02:12:05 +02:00
parent 0bd5896cee
commit 679df11aad
2 changed files with 28 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- (**Migration**) Show "abort" button during active bulk migration search - (**Migration**) Show "abort" button during active bulk migration search
- (**Migration**) Keep the migration page open when aborting during the actual migration execution - (**Migration**) Keep the migration page open when aborting during the actual migration execution
- (**Migration**) Prevent concurrent requests to the same tracker
### Fixed ### Fixed

View File

@@ -25,6 +25,9 @@ import type {
} from '@/features/chapter/Chapter.types.ts'; } from '@/features/chapter/Chapter.types.ts';
import type { GqlMetaHolder } from '@/features/metadata/Metadata.types.ts'; import type { GqlMetaHolder } from '@/features/metadata/Metadata.types.ts';
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts'; import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
import { Queue } from '@/lib/Queue.ts';
import type { TrackerIdInfo } from '@/features/tracker/Tracker.types.ts';
import { assertIsDefined } from '@/base/Asserts.ts';
type MangaToMigrate = NonNullable<GetMangaToMigrateQuery['manga']>; type MangaToMigrate = NonNullable<GetMangaToMigrateQuery['manga']>;
type MangaToMigrateTo = NonNullable<GetMangaToMigrateToFetchMutation['fetchManga']>['manga']; type MangaToMigrateTo = NonNullable<GetMangaToMigrateToFetchMutation['fetchManga']>['manga'];
@@ -43,6 +46,20 @@ const performMigrationAction = async (migrateAction: keyof MigrateAction, ...act
Promise.all(actions.flatMap((action) => action[migrateAction]())); Promise.all(actions.flatMap((action) => action[migrateAction]()));
export class MangaMigration { export class MangaMigration {
private static trackerQueue = new Map<TrackerIdInfo['id'], Queue>();
private static getOrCreateQueue(trackerId: TrackerIdInfo['id']): Queue {
if (!MangaMigration.trackerQueue.has(trackerId)) {
MangaMigration.trackerQueue.set(trackerId, new Queue(1));
}
const queue = MangaMigration.trackerQueue.get(trackerId);
assertIsDefined(queue);
return queue;
}
static async migrate( static async migrate(
mangaToMigrate: MangaToMigrate | null | undefined, mangaToMigrate: MangaToMigrate | null | undefined,
mangaToMigrateTo: MangaToMigrateTo | null | undefined, mangaToMigrateTo: MangaToMigrateTo | null | undefined,
@@ -281,12 +298,16 @@ export class MangaMigration {
copy: () => copy: () =>
trackBindingsToAdd.map( trackBindingsToAdd.map(
(trackRecord) => (trackRecord) =>
requestManager.bindTracker( MangaMigration.getOrCreateQueue(trackRecord.trackerId).enqueue(
mangaToMigrateTo.id, String(mangaToMigrate.id),
trackRecord.trackerId, () =>
trackRecord.remoteId, requestManager.bindTracker(
trackRecord.private, mangaToMigrateTo.id,
).response, trackRecord.trackerId,
trackRecord.remoteId,
trackRecord.private,
).response,
).promise,
), ),
cleanup: () => cleanup: () =>
mode === 'migrate' mode === 'migrate'