diff --git a/packages/@sanity/migrate/src/_exports/index.ts b/packages/@sanity/migrate/src/_exports/index.ts index 6d756e96ecbe..e1fc8b940006 100644 --- a/packages/@sanity/migrate/src/_exports/index.ts +++ b/packages/@sanity/migrate/src/_exports/index.ts @@ -7,3 +7,4 @@ export * from '../it-utils' export * from '../runner/run' export * from '../runner/dryRun' export * from '../runner/collectMigrationMutations' +export {MAX_MUTATION_CONCURRENCY} from '../runner/constants' diff --git a/packages/@sanity/migrate/src/runner/constants.ts b/packages/@sanity/migrate/src/runner/constants.ts index 22eaa57c134b..d4269c574939 100644 --- a/packages/@sanity/migrate/src/runner/constants.ts +++ b/packages/@sanity/migrate/src/runner/constants.ts @@ -1,2 +1,3 @@ export const MUTATION_ENDPOINT_MAX_BODY_SIZE = 1024 * 256 // 256KB export const DEFAULT_MUTATION_CONCURRENCY = 6 +export const MAX_MUTATION_CONCURRENCY = 10 diff --git a/packages/@sanity/migrate/src/runner/run.ts b/packages/@sanity/migrate/src/runner/run.ts index debcfe63beff..9bad754b6fd9 100644 --- a/packages/@sanity/migrate/src/runner/run.ts +++ b/packages/@sanity/migrate/src/runner/run.ts @@ -8,7 +8,11 @@ import {toFetchOptions} from '../fetch-utils/sanityRequestOptions' import {commitMutations} from '../destinations/commitMutations' import {collectMigrationMutations} from './collectMigrationMutations' import {batchMutations} from './utils/batchMutations' -import {DEFAULT_MUTATION_CONCURRENCY, MUTATION_ENDPOINT_MAX_BODY_SIZE} from './constants' +import { + DEFAULT_MUTATION_CONCURRENCY, + MAX_MUTATION_CONCURRENCY, + MUTATION_ENDPOINT_MAX_BODY_SIZE, +} from './constants' import {toSanityMutations} from './utils/toSanityMutations' interface MigrationRunnerOptions { @@ -37,10 +41,11 @@ export async function* run(config: MigrationRunnerOptions, migration: Migration) ndjson(await fromExportEndpoint(config.api)) as AsyncIterableIterator, ) - const concurrency = Math.min( - DEFAULT_MUTATION_CONCURRENCY, - config?.concurrency ?? DEFAULT_MUTATION_CONCURRENCY, - ) + const concurrency = config?.concurrency ?? DEFAULT_MUTATION_CONCURRENCY + + if (concurrency > MAX_MUTATION_CONCURRENCY) { + throw new Error(`Concurrency exceeds maximum allowed value (${MAX_MUTATION_CONCURRENCY})`) + } const batches = batchMutations(toSanityMutations(mutations), MUTATION_ENDPOINT_MAX_BODY_SIZE) diff --git a/packages/sanity/src/_internal/cli/commands/migration/runMigrationCommand.ts b/packages/sanity/src/_internal/cli/commands/migration/runMigrationCommand.ts index 91f4b9d5c741..84eb56f56d3f 100644 --- a/packages/sanity/src/_internal/cli/commands/migration/runMigrationCommand.ts +++ b/packages/sanity/src/_internal/cli/commands/migration/runMigrationCommand.ts @@ -6,6 +6,7 @@ import { collectMigrationMutations, fromExportArchive, fromExportEndpoint, + MAX_MUTATION_CONCURRENCY, Migration, ndjson, run, @@ -15,7 +16,10 @@ import {format} from './mutationFormatter' const helpText = ` Options - --dryRun Whether or not to dry run the migration. Default to true, to actually run the migration this has to be set to false + --dry Whether or not to dry run the migration. Default to true, to actually run the migration this has to be set to false + --from-export Use a local dataset export as source for migration instead of calling the Sanity API. Note: this is only supported for dry runs. + --concurrency How many mutation requests to run in parallel. Might be subject to an upper hard limit. + Examples sanity migration run @@ -26,6 +30,7 @@ Examples interface CreateFlags { dry?: 'true' | 'false' | 'yes' | 'no' 'from-export'?: string + concurrency?: number } const tryExtensions = ['mjs', 'js', 'ts', 'cjs'] @@ -111,6 +116,18 @@ const createMigrationCommand: CliCommandDefinition = { throw new Error('Can only dry run migrations from a dataset export file') } + let concurrency = args.extOptions.concurrency + if (concurrency !== undefined) { + if (concurrency > MAX_MUTATION_CONCURRENCY) { + concurrency = MAX_MUTATION_CONCURRENCY + console.warn( + 'Provided concurrency exceeds maximum and is is limited to %d', + MAX_MUTATION_CONCURRENCY, + ) + } + concurrency = MAX_MUTATION_CONCURRENCY + } + const {dataset, projectId, apiHost, token} = apiClient({ requireUser: true, requireProject: true, @@ -126,7 +143,7 @@ const createMigrationCommand: CliCommandDefinition = { const progress = dry ? dryRun({api: apiConfig}, migration, context) - : run({api: apiConfig}, migration) + : run({api: apiConfig, concurrency}, migration) for await (const result of progress) { output.print(result)