You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 22, 2025. It is now read-only.
logger().warn("could not find persisted connection to remove",{
763
766
connId: conn.id,
@@ -1048,8 +1051,12 @@ export class ActorInstance<
1048
1051
}
1049
1052
}
1050
1053
1051
-
#assertReady(){
1054
+
#assertReady(allowStoppingState: boolean=false){
1052
1055
if(!this.#ready)thrownewerrors.InternalError("Actor not ready");
1056
+
if(!allowStoppingState&&this.#sleepCalled)
1057
+
thrownewerrors.InternalError("Actor is going to sleep");
1058
+
if(!allowStoppingState&&this.#stopCalled)
1059
+
thrownewerrors.InternalError("Actor is stopping");
1053
1060
}
1054
1061
1055
1062
/**
@@ -1443,24 +1450,24 @@ export class ActorInstance<
1443
1450
}
1444
1451
1445
1452
/**
1446
-
* Runs a promise in the background.
1453
+
* Prevents the actor from sleeping until promise is complete.
1447
1454
*
1448
1455
* This allows the actor runtime to ensure that a promise completes while
1449
1456
* returning from an action request early.
1450
1457
*
1451
1458
* @param promise - The promise to run in the background.
1452
1459
*/
1453
-
_runInBackground(promise: Promise<void>){
1460
+
_waitUntil(promise: Promise<void>){
1454
1461
this.#assertReady();
1455
1462
1456
1463
// TODO: Should we force save the state?
1457
1464
// Add logging to promise and make it non-failable
1458
1465
constnonfailablePromise=promise
1459
1466
.then(()=>{
1460
-
logger().debug("background promise complete");
1467
+
logger().debug("wait until promise complete");
1461
1468
})
1462
1469
.catch((error)=>{
1463
-
logger().error("background promise failed",{
1470
+
logger().error("wait until promise failed",{
1464
1471
error: stringifyError(error),
1465
1472
});
1466
1473
});
@@ -1476,7 +1483,7 @@ export class ActorInstance<
1476
1483
* @param opts - Options for saving the state.
1477
1484
*/
1478
1485
asyncsaveState(opts: SaveStateOptions){
1479
-
this.#assertReady();
1486
+
this.#assertReady(opts.allowStoppingState);
1480
1487
1481
1488
if(this.#persistChanged){
1482
1489
if(opts.immediate){
@@ -1552,7 +1559,7 @@ export class ActorInstance<
1552
1559
returntrue;
1553
1560
}
1554
1561
1555
-
/** Puts an actor to sleep. */
1562
+
/** Puts an actor to sleep. This should just start the sleep sequence, most shutdown logic should be in _stop (which is called by the ActorDriver when sleeping). */
1556
1563
async_sleep(){
1557
1564
invariant(this.#sleepingSupported,"sleeping not supported");
1558
1565
invariant(this.#actorDriver.sleep,"no sleep on driver");
@@ -1581,6 +1588,11 @@ export class ActorInstance<
1581
1588
1582
1589
logger().info("actor stopping");
1583
1590
1591
+
// Abort any listeners waiting for shutdown
1592
+
try{
1593
+
this.#abortController.abort();
1594
+
}catch{}
1595
+
1584
1596
// Call onStop lifecycle hook if defined
1585
1597
if(this.#config.onStop){
1586
1598
try{
@@ -1601,8 +1613,11 @@ export class ActorInstance<
1601
1613
}
1602
1614
}
1603
1615
1616
+
// Wait for any background tasks to finish, with timeout
0 commit comments