@@ -48,6 +48,8 @@ type CheckpointerOptions = {
4848  chaosMonkey ?: ChaosMonkey ; 
4949} ; 
5050
51+ class  CheckpointAbortError  extends  Error  { } 
52+ 
5153async  function  getFileSize ( filePath : string ) : Promise < number >  { 
5254  try  { 
5355    const  stats  =  await  fs . stat ( filePath ) ; 
@@ -248,7 +250,12 @@ export class Checkpointer {
248250      return  false ; 
249251    } 
250252
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()" ) ; 
252259    this . #abortControllers. delete ( runId ) ; 
253260
254261    return  true ; 
@@ -395,6 +402,14 @@ export class Checkpointer {
395402    const  controller  =  new  AbortController ( ) ; 
396403    this . #abortControllers. set ( runId ,  controller ) ; 
397404
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+ 
398413    const  $$  =  $ ( {  signal : controller . signal  } ) ; 
399414
400415    const  shortCode  =  nanoid ( 8 ) ; 
@@ -418,6 +433,7 @@ export class Checkpointer {
418433    } ; 
419434
420435    try  { 
436+       assertNotAborted ( "chaosMonkey.call" ) ; 
421437      await  this . chaosMonkey . call ( {  $ : $$  } ) ; 
422438
423439      this . #logger. log ( "Checkpointing:" ,  {  options } ) ; 
@@ -474,11 +490,12 @@ export class Checkpointer {
474490        return  {  success : false ,  reason : "SKIP_RETRYING"  } ; 
475491      } 
476492
493+       assertNotAborted ( "cmd: crictl ps" ) ; 
477494      const  containerId  =  this . #logger. debug ( 
478495        // @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 " }  ` ) 
482499      ) ; 
483500
484501      if  ( ! containerId . stdout )  { 
@@ -496,6 +513,7 @@ export class Checkpointer {
496513      } 
497514
498515      // Create checkpoint 
516+       assertNotAborted ( "cmd: crictl checkpoint" ) ; 
499517      this . #logger. debug ( await  $$ `crictl checkpoint --export=${ exportLocation }   ${ containerId }  ` ) ; 
500518      const  postCheckpoint  =  performance . now ( ) ; 
501519
@@ -504,20 +522,25 @@ export class Checkpointer {
504522      this . #logger. log ( "checkpoint archive created" ,  {  size,  options } ) ; 
505523
506524      // Create image from checkpoint 
525+       assertNotAborted ( "cmd: buildah from scratch" ) ; 
507526      const  container  =  this . #logger. debug ( await  $$ `buildah from scratch` ) ; 
508527      const  postFrom  =  performance . now ( ) ; 
509528
529+       assertNotAborted ( "cmd: buildah add" ) ; 
510530      this . #logger. debug ( await  $$ `buildah add ${ container }   ${ exportLocation }   /` ) ; 
511531      const  postAdd  =  performance . now ( ) ; 
512532
533+       assertNotAborted ( "cmd: buildah config" ) ; 
513534      this . #logger. debug ( 
514535        await  $$ `buildah config --annotation=io.kubernetes.cri-o.annotations.checkpoint.name=counter ${ container }  ` 
515536      ) ; 
516537      const  postConfig  =  performance . now ( ) ; 
517538
539+       assertNotAborted ( "cmd: buildah commit" ) ; 
518540      this . #logger. debug ( await  $$ `buildah commit ${ container }   ${ imageRef }  ` ) ; 
519541      const  postCommit  =  performance . now ( ) ; 
520542
543+       assertNotAborted ( "cmd: buildah rm" ) ; 
521544      this . #logger. debug ( await  $$ `buildah rm ${ container }  ` ) ; 
522545      const  postRm  =  performance . now ( ) ; 
523546
@@ -529,6 +552,7 @@ export class Checkpointer {
529552      } 
530553
531554      // Push checkpoint image 
555+       assertNotAborted ( "cmd: buildah push" ) ; 
532556      this . #logger. debug ( 
533557        await  $$ `buildah push --tls-verify=${ String ( this . registryTlsVerify ) }   ${ imageRef }  ` 
534558      ) ; 
@@ -554,9 +578,15 @@ export class Checkpointer {
554578        } , 
555579      } ; 
556580    }  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+ 
557587      if  ( isExecaChildProcess ( error ) )  { 
558588        if  ( error . isCanceled )  { 
559-           this . #logger. error ( "Checkpoint canceled" ,  {  options,  error } ) ; 
589+           this . #logger. error ( "Checkpoint canceled: ExecaChildProcess " ,  {  options,  error } ) ; 
560590
561591          return  {  success : false ,  reason : "CANCELED"  } ; 
562592        } 
0 commit comments