From a467b280c1d408eb861dafadd5914d67de3af485 Mon Sep 17 00:00:00 2001 From: SammyBits Date: Sat, 29 Aug 2026 17:25:06 -0400 Subject: [PATCH] feat(faseF2): DELTIX_ENABLE_GRPC_TRANSFER flag gates the legacy gRPC pull Native commit-based pull (Fase C) is now the default. To allow a safe rollback while it is confirmed in production, the old whole-file gRPC pull is kept behind an opt-in feature flag: - env: DELTIX_ENABLE_GRPC_TRANSFER (default false). - 'deltix pull ' uses the legacy gRPC DataflowService.pull only when the flag is on AND a destination file is passed; otherwise the native REST pull runs. Dataflow is a lazy import so it only loads when used. Marked transitional: the gRPC pull path is removed in a later phase once the native path is confirmed. 113 unit tests pass, build + lint clean. --- src/cli/index.ts | 23 ++++++++++++++++++++++- src/shared/env.ts | 9 +++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/cli/index.ts b/src/cli/index.ts index 04d7c62..78813d6 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -208,7 +208,28 @@ function handleSyncError(err: unknown, action: string): number { async function runPull(args: string[]): Promise { const abort = args.includes('--abort'); - const repoArg = args.find((a) => !a.startsWith('--')); + const positional = args.filter((a) => !a.startsWith('--')); + const repoArg = positional[0]; + const destFile = positional[1]; + + // Transitional legacy path: whole-file gRPC pull, behind + // DELTIX_ENABLE_GRPC_TRANSFER. Removed once the native commit-based pull is + // confirmed in production. + if (loadEnv().DELTIX_ENABLE_GRPC_TRANSFER && repoArg && destFile) { + const { createDataflowService } = await import('../contexts/dataflow'); + try { + const result = await createDataflowService().pull(repoArg, destFile); + printSuccess(`[legacy gRPC] Pull completed for ${repoArg}`, { + bytesReceived: result.bytesReceived, + checksum: result.checksum, + }); + return 0; + } catch (err) { + printError(`Pull failed (legacy gRPC): ${String(err)}`); + return 1; + } + } + const identity = await resolveServerIdentity(repoArg); if (!identity) { return 1; diff --git a/src/shared/env.ts b/src/shared/env.ts index 04d904f..261d037 100644 --- a/src/shared/env.ts +++ b/src/shared/env.ts @@ -61,6 +61,15 @@ const envSchema = z.object({ // when the host already runs a real MySQL service. DELTIX_LOCAL_HOST: z.string().min(1).default('127.0.0.1'), DELTIX_LOCAL_PORT: z.coerce.number().int().positive().default(3306), + // Transitional feature flag (Fase 5.9). `deltix pull` is now commit-based + // over REST (native, git-like). When this is enabled AND a destination file + // is passed, `deltix pull` falls back to the legacy whole-file gRPC transfer + // instead. Off by default; kept only to allow an easy rollback/comparison + // until the native path is fully confirmed, then the gRPC pull path is removed. + DELTIX_ENABLE_GRPC_TRANSFER: z + .enum(['true', 'false', '1', '0']) + .default('false') + .transform((v) => v === 'true' || v === '1'), }); export type Env = z.infer;