Skip to content

Commit 233dac7

Browse files
Change waitForProcessing to use exponential backoff
1 parent 0e150e4 commit 233dac7

1 file changed

Lines changed: 28 additions & 19 deletions

File tree

src/upload-lib.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,10 @@ function dumpSarifFile(
829829
fs.writeFileSync(outputFile, sarifPayload);
830830
}
831831

832-
const STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1000;
833-
const STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1000;
832+
// Should lead to status checks after 5s, 15s, 35s, 75s, and 155s.
833+
const STATUS_CHECK_INITIAL_BACKOFF_MILLISECONDS = 5 * 1000;
834+
const STATUS_CHECK_BACKOFF_MULTIPLIER = 2;
835+
const STATUS_CHECK_MAX_TRIES = 5;
834836

835837
type ProcessingStatus = "pending" | "complete" | "failed";
836838

@@ -854,20 +856,16 @@ export async function waitForProcessing(
854856
try {
855857
const client = api.getApiClient();
856858

857-
const statusCheckingStarted = Date.now();
858-
while (true) {
859-
if (
860-
Date.now() >
861-
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS
862-
) {
863-
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
864-
// It's possible the analysis will eventually finish processing, but it's not worth spending more
865-
// Actions time waiting.
866-
logger.warning(
867-
"Timed out waiting for analysis to finish processing. Continuing.",
868-
);
869-
break;
870-
}
859+
// Do an initial wait because processing will always take a minimum of 2-3 seconds
860+
let statusCheckBackoff = STATUS_CHECK_INITIAL_BACKOFF_MILLISECONDS;
861+
await util.delay(statusCheckBackoff, { allowProcessExit: false });
862+
863+
let timedOut = true;
864+
for (
865+
let statusCheckingCount = 0;
866+
statusCheckingCount < STATUS_CHECK_MAX_TRIES;
867+
statusCheckingCount++
868+
) {
871869
let response: OctokitResponse<any> | undefined = undefined;
872870
try {
873871
response = await client.request(
@@ -882,6 +880,7 @@ export async function waitForProcessing(
882880
logger.warning(
883881
`An error occurred checking the status of the delivery. ${e} It should still be processed in the background, but errors that occur during processing may not be reported.`,
884882
);
883+
timedOut = false;
885884
break;
886885
}
887886
const status = response.data.processing_status as ProcessingStatus;
@@ -897,8 +896,10 @@ export async function waitForProcessing(
897896
status,
898897
logger,
899898
);
899+
timedOut = false;
900900
break;
901901
} else if (status === "complete") {
902+
timedOut = false;
902903
break;
903904
} else if (status === "failed") {
904905
const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`;
@@ -912,9 +913,17 @@ export async function waitForProcessing(
912913
util.assertNever(status);
913914
}
914915

915-
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS, {
916-
allowProcessExit: false,
917-
});
916+
statusCheckBackoff *= STATUS_CHECK_BACKOFF_MULTIPLIER;
917+
await util.delay(statusCheckBackoff, { allowProcessExit: false });
918+
}
919+
920+
if (timedOut) {
921+
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
922+
// It's possible the analysis will eventually finish processing, but it's not worth spending more
923+
// Actions time waiting.
924+
logger.warning(
925+
"Timed out waiting for analysis to finish processing. Continuing.",
926+
);
918927
}
919928
} finally {
920929
logger.endGroup();

0 commit comments

Comments
 (0)