From 1fc242200f78e4219aafc5bb91de8cf0916236af Mon Sep 17 00:00:00 2001 From: Christina Ying Wang Date: Mon, 6 Jan 2025 14:21:27 -0800 Subject: [PATCH] Revert to regular pull immediately on delta server failure (code 400s) If the delta server responds immediately with HTTP 4xx upon requesting a delta image, this means the server is not able to supply the resource, so fall back to a regular pull immediately. Change-type: patch Signed-off-by: Christina Ying Wang --- src/lib/docker-utils.ts | 16 +++++++++++----- src/lib/errors.ts | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/lib/docker-utils.ts b/src/lib/docker-utils.ts index 25845154..056c3066 100644 --- a/src/lib/docker-utils.ts +++ b/src/lib/docker-utils.ts @@ -12,6 +12,7 @@ import { DeltaStillProcessingError, ImageAuthenticationError, InvalidNetGatewayError, + DeltaServerError, } from './errors'; import * as request from './request'; import type { EnvVarObject } from '../types'; @@ -113,11 +114,7 @@ export async function fetchDeltaWithProgress( onProgress: ProgressCallback, serviceName: string, ): Promise { - const deltaSourceId = - deltaOpts.deltaSourceId != null - ? deltaOpts.deltaSourceId - : deltaOpts.deltaSource; - + const deltaSourceId = deltaOpts.deltaSourceId ?? deltaOpts.deltaSource; const timeout = deltaOpts.deltaApplyTimeout; const logFn = (str: string) => @@ -210,6 +207,10 @@ export async function fetchDeltaWithProgress( } break; case 3: + // If 400s status code, throw a more specific error & revert immediately to a regular pull + if (res.statusCode >= 400 && res.statusCode < 500) { + throw new DeltaServerError(res.statusCode, res.statusMessage); + } if (res.statusCode !== 200) { throw new Error( `Got ${res.statusCode} when requesting v3 delta from delta server.`, @@ -235,6 +236,11 @@ export async function fetchDeltaWithProgress( if (e instanceof OutOfSyncError) { logFn('Falling back to regular pull due to delta out of sync error'); return await fetchImageWithProgress(imgDest, deltaOpts, onProgress); + } else if (e instanceof DeltaServerError) { + logFn( + `Falling back to regular pull due to delta server error (${e.statusCode})${e.statusMessage ? `: ${e.statusMessage}` : ''}`, + ); + return await fetchImageWithProgress(imgDest, deltaOpts, onProgress); } else { logFn(`Delta failed with ${e}`); throw e; diff --git a/src/lib/errors.ts b/src/lib/errors.ts index eb4a1a08..f7979f1f 100644 --- a/src/lib/errors.ts +++ b/src/lib/errors.ts @@ -70,6 +70,8 @@ export class InvalidNetGatewayError extends TypedError {} export class DeltaStillProcessingError extends TypedError {} +export class DeltaServerError extends StatusError {} + export class UpdatesLockedError extends TypedError {} export function isHttpConflictError(err: { statusCode: number }): boolean {