@@ -223,33 +223,36 @@ export async function processBatch(
223223 return { repoId : target . repoId , status : 'extractor-failed' as const }
224224 }
225225 } )
226+
227+ const extractionDurationMs = Date . now ( ) - extractionStartedAt
228+ const ok = outcomes . filter ( ( o ) => o . status === 'ok' ) . length
229+ log . info (
230+ {
231+ ok,
232+ failed : outcomes . length - ok ,
233+ durationMs : extractionDurationMs ,
234+ reposPerSec : Number ( ( outcomes . length / ( extractionDurationMs / 1000 ) ) . toFixed ( 1 ) ) ,
235+ } ,
236+ 'Security contacts batch extraction complete — persisting' ,
237+ )
238+
239+ // Heartbeat is kept alive through persistence too: a slow/lock-blocked write can outlast the
240+ // 2-minute heartbeat timeout just like extraction can, and letting the timer stop early would
241+ // let Temporal retry this activity while the original attempt is still writing.
242+ const writeStartedAt = Date . now ( )
243+ await writeContactsBatch ( qx , outcomes )
244+ const writeDurationMs = Date . now ( ) - writeStartedAt
245+ log . info (
246+ {
247+ durationMs : writeDurationMs ,
248+ reposPerSec : Number ( ( outcomes . length / ( writeDurationMs / 1000 ) ) . toFixed ( 1 ) ) ,
249+ } ,
250+ 'Security contacts batch persistence complete' ,
251+ )
226252 } finally {
227253 clearInterval ( heartbeatTimer )
228254 }
229255
230- const extractionDurationMs = Date . now ( ) - extractionStartedAt
231- const ok = outcomes . filter ( ( o ) => o . status === 'ok' ) . length
232- log . info (
233- {
234- ok,
235- failed : outcomes . length - ok ,
236- durationMs : extractionDurationMs ,
237- reposPerSec : Number ( ( outcomes . length / ( extractionDurationMs / 1000 ) ) . toFixed ( 1 ) ) ,
238- } ,
239- 'Security contacts batch extraction complete — persisting' ,
240- )
241-
242- const writeStartedAt = Date . now ( )
243- await writeContactsBatch ( qx , outcomes )
244- const writeDurationMs = Date . now ( ) - writeStartedAt
245- log . info (
246- {
247- durationMs : writeDurationMs ,
248- reposPerSec : Number ( ( outcomes . length / ( writeDurationMs / 1000 ) ) . toFixed ( 1 ) ) ,
249- } ,
250- 'Security contacts batch persistence complete' ,
251- )
252-
253256 log . info ( { processed : targets . length } , 'Security contacts batch complete' )
254257 return { processed : targets . length }
255258}
0 commit comments