@@ -48,6 +48,8 @@ type CheckpointerOptions = {
48
48
chaosMonkey ?: ChaosMonkey ;
49
49
} ;
50
50
51
+ class CheckpointAbortError extends Error { }
52
+
51
53
async function getFileSize ( filePath : string ) : Promise < number > {
52
54
try {
53
55
const stats = await fs . stat ( filePath ) ;
@@ -248,7 +250,12 @@ export class Checkpointer {
248
250
return false ;
249
251
}
250
252
251
- controller . abort ( "cancelCheckpointing()" ) ;
253
+ if ( controller . signal . aborted ) {
254
+ this . #logger. debug ( "Controller already aborted" , { runId } ) ;
255
+ return false ;
256
+ }
257
+
258
+ controller . abort ( "cancelCheckpoint()" ) ;
252
259
this . #abortControllers. delete ( runId ) ;
253
260
254
261
return true ;
@@ -395,6 +402,14 @@ export class Checkpointer {
395
402
const controller = new AbortController ( ) ;
396
403
this . #abortControllers. set ( runId , controller ) ;
397
404
405
+ const assertNotAborted = ( abortMessage ?: string ) => {
406
+ if ( controller . signal . aborted ) {
407
+ throw new CheckpointAbortError ( abortMessage ) ;
408
+ }
409
+
410
+ this . #logger. debug ( "Not aborted" , { abortMessage } ) ;
411
+ } ;
412
+
398
413
const $$ = $ ( { signal : controller . signal } ) ;
399
414
400
415
const shortCode = nanoid ( 8 ) ;
@@ -418,6 +433,7 @@ export class Checkpointer {
418
433
} ;
419
434
420
435
try {
436
+ assertNotAborted ( "chaosMonkey.call" ) ;
421
437
await this . chaosMonkey . call ( { $ : $$ } ) ;
422
438
423
439
this . #logger. log ( "Checkpointing:" , { options } ) ;
@@ -474,11 +490,12 @@ export class Checkpointer {
474
490
return { success : false , reason : "SKIP_RETRYING" } ;
475
491
}
476
492
493
+ assertNotAborted ( "cmd: crictl ps" ) ;
477
494
const containerId = this . #logger. debug (
478
495
// @ts -expect-error
479
- await $$ `crictl ps`
480
- . pipeStdout ( $$ ( { stdin : "pipe" } ) `grep ${ containterName } ` )
481
- . pipeStdout ( $$ ( { stdin : "pipe" } ) `cut -f1 ${ "-d " } ` )
496
+ await $ `crictl ps`
497
+ . pipeStdout ( $ ( { stdin : "pipe" } ) `grep ${ containterName } ` )
498
+ . pipeStdout ( $ ( { stdin : "pipe" } ) `cut -f1 ${ "-d " } ` )
482
499
) ;
483
500
484
501
if ( ! containerId . stdout ) {
@@ -496,6 +513,7 @@ export class Checkpointer {
496
513
}
497
514
498
515
// Create checkpoint
516
+ assertNotAborted ( "cmd: crictl checkpoint" ) ;
499
517
this . #logger. debug ( await $$ `crictl checkpoint --export=${ exportLocation } ${ containerId } ` ) ;
500
518
const postCheckpoint = performance . now ( ) ;
501
519
@@ -504,20 +522,25 @@ export class Checkpointer {
504
522
this . #logger. log ( "checkpoint archive created" , { size, options } ) ;
505
523
506
524
// Create image from checkpoint
525
+ assertNotAborted ( "cmd: buildah from scratch" ) ;
507
526
const container = this . #logger. debug ( await $$ `buildah from scratch` ) ;
508
527
const postFrom = performance . now ( ) ;
509
528
529
+ assertNotAborted ( "cmd: buildah add" ) ;
510
530
this . #logger. debug ( await $$ `buildah add ${ container } ${ exportLocation } /` ) ;
511
531
const postAdd = performance . now ( ) ;
512
532
533
+ assertNotAborted ( "cmd: buildah config" ) ;
513
534
this . #logger. debug (
514
535
await $$ `buildah config --annotation=io.kubernetes.cri-o.annotations.checkpoint.name=counter ${ container } `
515
536
) ;
516
537
const postConfig = performance . now ( ) ;
517
538
539
+ assertNotAborted ( "cmd: buildah commit" ) ;
518
540
this . #logger. debug ( await $$ `buildah commit ${ container } ${ imageRef } ` ) ;
519
541
const postCommit = performance . now ( ) ;
520
542
543
+ assertNotAborted ( "cmd: buildah rm" ) ;
521
544
this . #logger. debug ( await $$ `buildah rm ${ container } ` ) ;
522
545
const postRm = performance . now ( ) ;
523
546
@@ -529,6 +552,7 @@ export class Checkpointer {
529
552
}
530
553
531
554
// Push checkpoint image
555
+ assertNotAborted ( "cmd: buildah push" ) ;
532
556
this . #logger. debug (
533
557
await $$ `buildah push --tls-verify=${ String ( this . registryTlsVerify ) } ${ imageRef } `
534
558
) ;
@@ -554,9 +578,15 @@ export class Checkpointer {
554
578
} ,
555
579
} ;
556
580
} catch ( error ) {
581
+ if ( error instanceof CheckpointAbortError ) {
582
+ this . #logger. error ( "Checkpoint canceled: CheckpointAbortError" , { options, error } ) ;
583
+
584
+ return { success : false , reason : "CANCELED" } ;
585
+ }
586
+
557
587
if ( isExecaChildProcess ( error ) ) {
558
588
if ( error . isCanceled ) {
559
- this . #logger. error ( "Checkpoint canceled" , { options, error } ) ;
589
+ this . #logger. error ( "Checkpoint canceled: ExecaChildProcess " , { options, error } ) ;
560
590
561
591
return { success : false , reason : "CANCELED" } ;
562
592
}
0 commit comments