diff --git a/packages/cache/__tests__/options.test.ts b/packages/cache/__tests__/options.test.ts index 3075b43b..94b0e0eb 100644 --- a/packages/cache/__tests__/options.test.ts +++ b/packages/cache/__tests__/options.test.ts @@ -8,6 +8,7 @@ import { const useAzureSdk = true const downloadConcurrency = 8 const timeoutInMs = 30000 +const abortTimeInMs = 2700000 const uploadConcurrency = 4 const uploadChunkSize = 32 * 1024 * 1024 @@ -17,7 +18,8 @@ test('getDownloadOptions sets defaults', async () => { expect(actualOptions).toEqual({ useAzureSdk, downloadConcurrency, - timeoutInMs + timeoutInMs, + abortTimeInMs }) }) @@ -25,7 +27,8 @@ test('getDownloadOptions overrides all settings', async () => { const expectedOptions: DownloadOptions = { useAzureSdk: false, downloadConcurrency: 14, - timeoutInMs: 20000 + timeoutInMs: 20000, + abortTimeInMs: 2700000 } const actualOptions = getDownloadOptions(expectedOptions) diff --git a/packages/cache/src/internal/downloadUtils.ts b/packages/cache/src/internal/downloadUtils.ts index 1c0950c7..cccf2c0d 100644 --- a/packages/cache/src/internal/downloadUtils.ts +++ b/packages/cache/src/internal/downloadUtils.ts @@ -6,7 +6,6 @@ import * as buffer from 'buffer' import * as fs from 'fs' import * as stream from 'stream' import * as util from 'util' -import * as timer from 'timers/promises' import * as utils from './cacheUtils' import {SocketTimeout} from './constants' @@ -251,7 +250,6 @@ export async function downloadCacheStorageSDK( try { downloadProgress.startDisplayTimer() const controller = new AbortController(); - const timerController = new AbortController(); const abortSignal = controller.signal; while (!downloadProgress.isDone()) { const segmentStart = @@ -263,22 +261,20 @@ export async function downloadCacheStorageSDK( ) downloadProgress.nextSegment(segmentSize) - const result = await Promise.race([client.downloadToBuffer( - segmentStart, - segmentSize, - { - abortSignal: abortSignal, - concurrency: options.downloadConcurrency, - onProgress: downloadProgress.onProgress() - } - ), - timer.setTimeout(options.abortTimeInMs, 'timeout',{ signal: timerController.signal })]); - + const abortTimeInMs = options.abortTimeInMs == undefined ? 2700000 : options.abortTimeInMs; + const result = await promiseWithTimeout(abortTimeInMs, client.downloadToBuffer( + segmentStart, + segmentSize, + { + abortSignal: abortSignal, + concurrency: options.downloadConcurrency, + onProgress: downloadProgress.onProgress() + } + )); if(result === 'timeout') { controller.abort(); throw new Error("Download aborted, segment download timed out."); } else { - timerController.abort(); core.debug("Download completely successfully, cancelling timer.") } @@ -290,3 +286,18 @@ export async function downloadCacheStorageSDK( } } } + +const promiseWithTimeout = (timeoutMs: number, promise: Promise) => { + let timeoutHandle: NodeJS.Timeout; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutHandle = setTimeout(() => resolve('timeout'), timeoutMs); + }); + + return Promise.race([ + promise, + timeoutPromise, + ]).then((result) => { + clearTimeout(timeoutHandle); + return result; + }); +} \ No newline at end of file