@@ -9,11 +9,56 @@ const Errors = require('./Errors')
99const { notifyCLSICacheAboutBuild } = require ( './CLSICacheHandler' )
1010
1111let lastSuccessfulCompileTimestamp = 0
12+ const COMPILE_HEARTBEAT_INTERVAL_MS =
13+ Settings . clsi ?. compileHeartbeatMs ?? 10 * 1000
1214
1315function timeSinceLastSuccessfulCompile ( ) {
1416 return Date . now ( ) - lastSuccessfulCompileTimestamp
1517}
1618
19+ // Send interim 102 responses so upstream proxies/CDNs don't drop long-running compile requests.
20+ // We use writeProcessing() because it does not lock in the final HTTP status code.
21+ function startCompileHeartbeat ( res ) {
22+ const writeProcessing = res . writeProcessing ?. bind ( res )
23+ if ( ! writeProcessing || COMPILE_HEARTBEAT_INTERVAL_MS <= 0 ) {
24+ return ( ) => { }
25+ }
26+
27+ let stopped = false
28+ let timer
29+
30+ const stop = ( ) => {
31+ if ( stopped ) return
32+ stopped = true
33+ if ( timer ) clearInterval ( timer )
34+ if ( typeof res . removeListener === 'function' ) {
35+ res . removeListener ( 'close' , stop )
36+ res . removeListener ( 'finish' , stop )
37+ }
38+ }
39+
40+ const ping = ( ) => {
41+ if ( stopped || res . writableEnded ) {
42+ stop ( )
43+ return
44+ }
45+ try {
46+ writeProcessing ( )
47+ } catch ( err ) {
48+ logger . debug ( { err } , 'failed to send compile heartbeat' )
49+ stop ( )
50+ }
51+ }
52+
53+ ping ( )
54+ timer = setInterval ( ping , COMPILE_HEARTBEAT_INTERVAL_MS )
55+ if ( typeof res . on === 'function' ) {
56+ res . on ( 'close' , stop )
57+ res . on ( 'finish' , stop )
58+ }
59+ return stop
60+ }
61+
1762function compile ( req , res , next ) {
1863 const timer = new Metrics . Timer ( 'compile-request' )
1964 RequestParser . parse ( req . body , function ( error , request ) {
@@ -31,13 +76,15 @@ function compile(req, res, next) {
3176 if ( error ) {
3277 return next ( error )
3378 }
79+ const stopHeartbeat = startCompileHeartbeat ( res )
3480 const stats = { }
3581 const timings = { }
3682 CompileManager . doCompileWithLock (
3783 request ,
3884 stats ,
3985 timings ,
4086 ( error , result ) => {
87+ stopHeartbeat ( )
4188 let { buildId, outputFiles } = result || { }
4289 let code , status
4390 if ( outputFiles == null ) {
0 commit comments