@@ -447,7 +447,52 @@ export class Kernel {
447
447
448
448
let result ;
449
449
try {
450
- result = await promise ;
450
+ let settled = false ;
451
+ /**
452
+ * Poll for new callback requests until the promise is resolved. This is
453
+ * to allow any promises necessary for the promise to be able to settle.
454
+ * We use setImmediate so the next poll happens on the next run loop tick,
455
+ * after other microtasks might have been paused on a pending callback.
456
+ */
457
+ // eslint-disable-next-line no-inner-declarations
458
+ function pollForCallbacks ( kernel : Kernel ) {
459
+ // Promise has settled already, not going any further...
460
+ if ( settled ) {
461
+ return ;
462
+ }
463
+
464
+ for ( const [ cbid , cb ] of kernel . cbs . entries ( ) ) {
465
+ kernel . waiting . set ( cbid , cb ) ;
466
+ kernel . cbs . delete ( cbid ) ;
467
+ try {
468
+ cb . succeed (
469
+ kernel . callbackHandler ( {
470
+ cbid,
471
+ sync : false ,
472
+ cookie : cb . override . cookie ,
473
+ invoke : {
474
+ objref : cb . objref ,
475
+ method : cb . override . method ,
476
+ args : cb . args ,
477
+ } ,
478
+ } ) ,
479
+ ) ;
480
+ } catch ( err ) {
481
+ cb . fail ( err ) ;
482
+ } finally {
483
+ kernel . waiting . delete ( cbid ) ;
484
+ }
485
+ }
486
+ if ( ! settled ) {
487
+ setImmediate ( pollForCallbacks , kernel ) ;
488
+ }
489
+ }
490
+ pollForCallbacks ( this ) ;
491
+
492
+ result = await promise . finally ( ( ) => {
493
+ settled = true ;
494
+ } ) ;
495
+
451
496
this . _debug ( 'promise result:' , result ) ;
452
497
} catch ( e : any ) {
453
498
this . _debug ( 'promise error:' , e ) ;
@@ -475,14 +520,16 @@ export class Kernel {
475
520
} ;
476
521
}
477
522
523
+ /** @deprecated the flow should be handled directly by "end" */
478
524
public callbacks ( _req ?: api . CallbacksRequest ) : api . CallbacksResponse {
479
525
this . _debug ( 'callbacks' ) ;
480
526
const ret = Array . from ( this . cbs . entries ( ) ) . map ( ( [ cbid , cb ] ) => {
481
527
this . waiting . set ( cbid , cb ) ; // move to waiting
482
528
this . cbs . delete ( cbid ) ; // remove from created
483
529
const callback : api . Callback = {
484
- cbid,
485
530
cookie : cb . override . cookie ,
531
+ cbid,
532
+ sync : false ,
486
533
invoke : {
487
534
objref : cb . objref ,
488
535
method : cb . override . method ,
@@ -758,6 +805,7 @@ export class Kernel {
758
805
const result = this . callbackHandler ( {
759
806
cookie : override . cookie ,
760
807
cbid : this . _makecbid ( ) ,
808
+ sync : true ,
761
809
get : { objref, property : propertyName } ,
762
810
} ) ;
763
811
this . _debug ( 'callback returned' , result ) ;
@@ -774,6 +822,7 @@ export class Kernel {
774
822
this . callbackHandler ( {
775
823
cookie : override . cookie ,
776
824
cbid : this . _makecbid ( ) ,
825
+ sync : true ,
777
826
set : {
778
827
objref,
779
828
property : propertyName ,
@@ -910,6 +959,7 @@ export class Kernel {
910
959
const result = this . callbackHandler ( {
911
960
cookie : override . cookie ,
912
961
cbid : this . _makecbid ( ) ,
962
+ sync : true ,
913
963
invoke : {
914
964
objref,
915
965
method : methodName ,
0 commit comments