@@ -5,6 +5,44 @@ import {
5
5
SubmissionResponse
6
6
} from './api/adminServiceSchemas.js'
7
7
import { getInput } from '@actions/core'
8
+
9
+ async function sleep ( ms : number ) : Promise < void > {
10
+ return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) )
11
+ }
12
+
13
+ async function retryWithExponentialBackoff < T > (
14
+ operation : ( ) => Promise < T > ,
15
+ maxRetries : number = 5 ,
16
+ baseDelay : number = 1000
17
+ ) : Promise < T > {
18
+ let lastError : Error
19
+
20
+ for ( let attempt = 1 ; attempt <= maxRetries ; attempt ++ ) {
21
+ try {
22
+ return await operation ( )
23
+ } catch ( error ) {
24
+ lastError = error as Error
25
+
26
+ if ( attempt === maxRetries ) {
27
+ throw lastError
28
+ }
29
+
30
+ // Calculate delay with exponential backoff
31
+ // For the last attempt (5th), ensure at least 30 seconds delay
32
+ let delay = baseDelay * Math . pow ( 2 , attempt - 1 )
33
+ if ( attempt === maxRetries - 1 ) {
34
+ delay = Math . max ( delay , 30000 ) // Ensure at least 30 seconds before last try
35
+ }
36
+
37
+ console . log (
38
+ `Attempt ${ attempt } failed: ${ lastError . message } . Retrying in ${ delay } ms...`
39
+ )
40
+ await sleep ( delay )
41
+ }
42
+ }
43
+
44
+ throw lastError !
45
+ }
8
46
export async function submitFeedback (
9
47
body : GradingScriptResult ,
10
48
token : string ,
@@ -13,31 +51,34 @@ export async function submitFeedback(
13
51
}
14
52
) : Promise < GradeResponse > {
15
53
const gradingServerURL = getInput ( 'grading_server' )
16
- const response = await fetch (
17
- `${ gradingServerURL } /functions/v1/autograder-submit-feedback${
18
- queryParams ?. autograder_regression_test_id
19
- ? `?autograder_regression_test_id=${ queryParams . autograder_regression_test_id } `
20
- : ''
21
- } `,
22
- {
23
- method : 'POST' ,
24
- body : JSON . stringify ( body ) ,
25
- headers : {
26
- 'Content-Type' : 'application/json' ,
27
- Authorization : `${ token } `
54
+
55
+ return retryWithExponentialBackoff ( async ( ) => {
56
+ const response = await fetch (
57
+ `${ gradingServerURL } /functions/v1/autograder-submit-feedback${
58
+ queryParams ?. autograder_regression_test_id
59
+ ? `?autograder_regression_test_id=${ queryParams . autograder_regression_test_id } `
60
+ : ''
61
+ } `,
62
+ {
63
+ method : 'POST' ,
64
+ body : JSON . stringify ( body ) ,
65
+ headers : {
66
+ 'Content-Type' : 'application/json' ,
67
+ Authorization : `${ token } `
68
+ }
28
69
}
29
- }
30
- )
31
- if ( ! response . ok ) {
32
- throw new Error ( `Failed to submit feedback: ${ response . statusText } ` )
33
- }
34
- const resp = ( await response . json ( ) ) as GradeResponse
35
- if ( resp . error ) {
36
- throw new Error (
37
- `Failed to submit feedback: ${ resp . error . message } ${ resp . error . details } `
38
70
)
39
- }
40
- return resp
71
+ if ( ! response . ok ) {
72
+ throw new Error ( `Failed to submit feedback: ${ response . statusText } ` )
73
+ }
74
+ const resp = ( await response . json ( ) ) as GradeResponse
75
+ if ( resp . error ) {
76
+ throw new Error (
77
+ `Failed to submit feedback: ${ resp . error . message } ${ resp . error . details } `
78
+ )
79
+ }
80
+ return resp
81
+ } )
41
82
}
42
83
43
84
export async function createSubmission ( token : string ) {
0 commit comments