Avoid unref-ing timer while awaiting status upload
We had a problem where `waitForProcessing` was not completing before the node process ends. This is because using `unref` would allow the node process to end without having the `delay` function complete.
This commit is contained in:
parent
e187d074ed
commit
a2487fb969
6 changed files with 43 additions and 16 deletions
4
lib/upload-lib.js
generated
4
lib/upload-lib.js
generated
|
|
@ -330,7 +330,9 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = {
|
|||
else {
|
||||
util.assertNever(status);
|
||||
}
|
||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS, {
|
||||
allowProcessExit: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
22
lib/util.js
generated
22
lib/util.js
generated
|
|
@ -455,10 +455,20 @@ async function bundleDb(config, language, codeql, dbName) {
|
|||
return databaseBundlePath;
|
||||
}
|
||||
exports.bundleDb = bundleDb;
|
||||
async function delay(milliseconds) {
|
||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||
// surrounding promise is being awaited.
|
||||
return new Promise((resolve) => setTimeout(resolve, milliseconds).unref());
|
||||
/**
|
||||
* @param milliseconds time to delay
|
||||
* @param opts options
|
||||
* @param opts.allowProcessExit if true, the timer will not prevent the process from exiting
|
||||
*/
|
||||
async function delay(milliseconds, { allowProcessExit }) {
|
||||
return new Promise((resolve) => {
|
||||
const timer = setTimeout(resolve, milliseconds);
|
||||
if (allowProcessExit) {
|
||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||
// surrounding promise is being awaited.
|
||||
timer.unref();
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.delay = delay;
|
||||
function isGoodVersion(versionSpec) {
|
||||
|
|
@ -636,7 +646,7 @@ async function withTimeout(timeoutMs, promise, onTimeout) {
|
|||
return result;
|
||||
};
|
||||
const timeoutTask = async () => {
|
||||
await delay(timeoutMs);
|
||||
await delay(timeoutMs, { allowProcessExit: true });
|
||||
if (!finished) {
|
||||
// Workaround: While the promise racing below will allow the main code
|
||||
// to continue, the process won't normally exit until the asynchronous
|
||||
|
|
@ -659,7 +669,7 @@ exports.withTimeout = withTimeout;
|
|||
async function checkForTimeout() {
|
||||
if (hadTimeout === true) {
|
||||
core.info("A timeout occurred, force exiting the process after 30 seconds to prevent hanging.");
|
||||
await delay(30000);
|
||||
await delay(30000, { allowProcessExit: true });
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -463,7 +463,9 @@ export async function waitForProcessing(
|
|||
util.assertNever(status);
|
||||
}
|
||||
|
||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS, {
|
||||
allowProcessExit: false,
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
logger.endGroup();
|
||||
|
|
|
|||
25
src/util.ts
25
src/util.ts
|
|
@ -548,10 +548,23 @@ export async function bundleDb(
|
|||
return databaseBundlePath;
|
||||
}
|
||||
|
||||
export async function delay(milliseconds: number) {
|
||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||
// surrounding promise is being awaited.
|
||||
return new Promise((resolve) => setTimeout(resolve, milliseconds).unref());
|
||||
/**
|
||||
* @param milliseconds time to delay
|
||||
* @param opts options
|
||||
* @param opts.allowProcessExit if true, the timer will not prevent the process from exiting
|
||||
*/
|
||||
export async function delay(
|
||||
milliseconds: number,
|
||||
{ allowProcessExit }: { allowProcessExit: boolean }
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
const timer = setTimeout(resolve, milliseconds);
|
||||
if (allowProcessExit) {
|
||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||
// surrounding promise is being awaited.
|
||||
timer.unref();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function isGoodVersion(versionSpec: string) {
|
||||
|
|
@ -748,7 +761,7 @@ export async function withTimeout<T>(
|
|||
return result;
|
||||
};
|
||||
const timeoutTask = async () => {
|
||||
await delay(timeoutMs);
|
||||
await delay(timeoutMs, { allowProcessExit: true });
|
||||
if (!finished) {
|
||||
// Workaround: While the promise racing below will allow the main code
|
||||
// to continue, the process won't normally exit until the asynchronous
|
||||
|
|
@ -773,7 +786,7 @@ export async function checkForTimeout() {
|
|||
core.info(
|
||||
"A timeout occurred, force exiting the process after 30 seconds to prevent hanging."
|
||||
);
|
||||
await delay(30_000);
|
||||
await delay(30_000, { allowProcessExit: true });
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue