diff --git a/README.md b/README.md index 541b115..eaa30e7 100644 --- a/README.md +++ b/README.md @@ -42,3 +42,8 @@ const restoreKeys = [ const cacheKey = await cache.restoreCache(paths, key, restoreKeys) ``` +##### Cache segment restore timeout + +A cache gets downloaded in multiple segments of fixed sizes (`1GB` for a `32-bit` runner and `2GB` for a `64-bit` runner). Sometimes, a segment download gets stuck which causes the workflow job to be stuck forever and fail. Version `v3.0.4` of cache package introduces a segment download timeout. The segment download timeout will allow the segment download to get aborted and hence allow the job to proceed with a cache miss. + +Default value of this timeout is 60 minutes and can be customized by specifying an [environment variable](https://docs.github.com/en/actions/learn-github-actions/environment-variables) named `SEGMENT_DOWNLOAD_TIMEOUT_MINS` with timeout value in minutes. \ No newline at end of file diff --git a/RELEASES.md b/RELEASES.md index 8fc7ba2..dcc91a3 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -80,4 +80,7 @@ - Added 1 hour timeout for the download stuck issue [#810](https://github.com/actions/cache/issues/810). ### 3.0.3 -- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810). \ No newline at end of file +- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810). + +### 3.0.4 +- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MIN`. Default is 60 minutes. \ No newline at end of file diff --git a/__tests__/options.test.ts b/__tests__/options.test.ts index 5ec7b14..83d9b22 100644 --- a/__tests__/options.test.ts +++ b/__tests__/options.test.ts @@ -55,3 +55,21 @@ test('getUploadOptions overrides all settings', async () => { expect(actualOptions).toEqual(expectedOptions) }) + +test('getDownloadOptions overrides download timeout minutes', async () => { + const expectedOptions: DownloadOptions = { + useAzureSdk: false, + downloadConcurrency: 14, + timeoutInMs: 20000, + segmentTimeoutInMs: 3600000 + } + process.env.SEGMENT_DOWNLOAD_TIMEOUT_MINS = '10' + const actualOptions = getDownloadOptions(expectedOptions) + + expect(actualOptions.useAzureSdk).toEqual(expectedOptions.useAzureSdk) + expect(actualOptions.downloadConcurrency).toEqual( + expectedOptions.downloadConcurrency + ) + expect(actualOptions.timeoutInMs).toEqual(expectedOptions.timeoutInMs) + expect(actualOptions.segmentTimeoutInMs).toEqual(600000) +}) diff --git a/package-lock.json b/package-lock.json index 87d24d4..0ea84f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/cache", - "version": "3.0.3", + "version": "3.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@actions/cache", - "version": "3.0.3", + "version": "3.0.4", "license": "MIT", "dependencies": { "@actions/core": "^1.2.6", diff --git a/package.json b/package.json index 476e856..6a3d476 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@actions/cache", - "version": "3.0.3", + "version": "3.0.4", "preview": true, "description": "Actions cache lib", "keywords": [ diff --git a/src/options.ts b/src/options.ts index eefe973..652899a 100644 --- a/src/options.ts +++ b/src/options.ts @@ -112,10 +112,22 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions { result.segmentTimeoutInMs = copy.segmentTimeoutInMs } } + const segmentDownloadTimeoutMins = + process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS'] + if ( + segmentDownloadTimeoutMins && + !isNaN(Number(segmentDownloadTimeoutMins)) && + isFinite(Number(segmentDownloadTimeoutMins)) + ) { + result.segmentTimeoutInMs = Number(segmentDownloadTimeoutMins) * 60 * 1000 + } core.debug(`Use Azure SDK: ${result.useAzureSdk}`) core.debug(`Download concurrency: ${result.downloadConcurrency}`) core.debug(`Request timeout (ms): ${result.timeoutInMs}`) + core.debug( + `Cache segment download timeout mins env var: ${process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS']}` + ) core.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`) return result