mirror of https://github.com/actions/toolkit
Added custom promise with timeout
parent
970264135a
commit
8be69a26ed
|
@ -8,6 +8,7 @@ import {
|
||||||
const useAzureSdk = true
|
const useAzureSdk = true
|
||||||
const downloadConcurrency = 8
|
const downloadConcurrency = 8
|
||||||
const timeoutInMs = 30000
|
const timeoutInMs = 30000
|
||||||
|
const abortTimeInMs = 2700000
|
||||||
const uploadConcurrency = 4
|
const uploadConcurrency = 4
|
||||||
const uploadChunkSize = 32 * 1024 * 1024
|
const uploadChunkSize = 32 * 1024 * 1024
|
||||||
|
|
||||||
|
@ -17,7 +18,8 @@ test('getDownloadOptions sets defaults', async () => {
|
||||||
expect(actualOptions).toEqual({
|
expect(actualOptions).toEqual({
|
||||||
useAzureSdk,
|
useAzureSdk,
|
||||||
downloadConcurrency,
|
downloadConcurrency,
|
||||||
timeoutInMs
|
timeoutInMs,
|
||||||
|
abortTimeInMs
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -25,7 +27,8 @@ test('getDownloadOptions overrides all settings', async () => {
|
||||||
const expectedOptions: DownloadOptions = {
|
const expectedOptions: DownloadOptions = {
|
||||||
useAzureSdk: false,
|
useAzureSdk: false,
|
||||||
downloadConcurrency: 14,
|
downloadConcurrency: 14,
|
||||||
timeoutInMs: 20000
|
timeoutInMs: 20000,
|
||||||
|
abortTimeInMs: 2700000
|
||||||
}
|
}
|
||||||
|
|
||||||
const actualOptions = getDownloadOptions(expectedOptions)
|
const actualOptions = getDownloadOptions(expectedOptions)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import * as buffer from 'buffer'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as stream from 'stream'
|
import * as stream from 'stream'
|
||||||
import * as util from 'util'
|
import * as util from 'util'
|
||||||
import * as timer from 'timers/promises'
|
|
||||||
|
|
||||||
import * as utils from './cacheUtils'
|
import * as utils from './cacheUtils'
|
||||||
import {SocketTimeout} from './constants'
|
import {SocketTimeout} from './constants'
|
||||||
|
@ -251,7 +250,6 @@ export async function downloadCacheStorageSDK(
|
||||||
try {
|
try {
|
||||||
downloadProgress.startDisplayTimer()
|
downloadProgress.startDisplayTimer()
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timerController = new AbortController();
|
|
||||||
const abortSignal = controller.signal;
|
const abortSignal = controller.signal;
|
||||||
while (!downloadProgress.isDone()) {
|
while (!downloadProgress.isDone()) {
|
||||||
const segmentStart =
|
const segmentStart =
|
||||||
|
@ -263,22 +261,20 @@ export async function downloadCacheStorageSDK(
|
||||||
)
|
)
|
||||||
|
|
||||||
downloadProgress.nextSegment(segmentSize)
|
downloadProgress.nextSegment(segmentSize)
|
||||||
const result = await Promise.race([client.downloadToBuffer(
|
const abortTimeInMs = options.abortTimeInMs == undefined ? 2700000 : options.abortTimeInMs;
|
||||||
segmentStart,
|
const result = await promiseWithTimeout(abortTimeInMs, client.downloadToBuffer(
|
||||||
segmentSize,
|
segmentStart,
|
||||||
{
|
segmentSize,
|
||||||
abortSignal: abortSignal,
|
{
|
||||||
concurrency: options.downloadConcurrency,
|
abortSignal: abortSignal,
|
||||||
onProgress: downloadProgress.onProgress()
|
concurrency: options.downloadConcurrency,
|
||||||
}
|
onProgress: downloadProgress.onProgress()
|
||||||
),
|
}
|
||||||
timer.setTimeout(options.abortTimeInMs, 'timeout',{ signal: timerController.signal })]);
|
));
|
||||||
|
|
||||||
if(result === 'timeout') {
|
if(result === 'timeout') {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
throw new Error("Download aborted, segment download timed out.");
|
throw new Error("Download aborted, segment download timed out.");
|
||||||
} else {
|
} else {
|
||||||
timerController.abort();
|
|
||||||
core.debug("Download completely successfully, cancelling timer.")
|
core.debug("Download completely successfully, cancelling timer.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,3 +286,18 @@ export async function downloadCacheStorageSDK(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const promiseWithTimeout = (timeoutMs: number, promise: Promise<any>) => {
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue