@@ -1194,17 +1194,32 @@ const startCompiledInternal: <
11941194 const shutdownMailbox = compactMailbox === undefined
11951195 ? Queue . shutdown ( queue ! )
11961196 : Effect . sync ( ( ) => closeCompactMailbox ( compactMailbox ) )
1197- const termination = yield * Deferred . make < ProcessTermination > ( )
11981197 const done = yield * Deferred . make < Output , Error | StoppedError > ( )
11991198 const awaitCompletion = Deferred . await ( done ) . pipe ( Effect . exit , Effect . asVoid )
12001199 const drainServices = onDemand ? yield * Effect . context < Requirements > ( ) : undefined
12011200 let worker : Fiber . Fiber < any , never > | undefined
12021201 let draining = false
12031202 let offerRevision = 0
12041203 let interruptRequested = false
1205- let terminationRequested = false
1206- let requestRuntimeTermination = ( requested : ProcessTermination ) : Effect . Effect < boolean > =>
1207- Deferred . succeed ( termination , requested )
1204+ let requestedTermination : ProcessTermination | undefined
1205+ let reservedTerminationSnapshot : RuntimeSnapshot < State , Error , Output > | undefined
1206+ let reserveRequestedTermination :
1207+ | ( ( requested : ProcessTermination ) => RuntimeSnapshot < State , Error , Output > | undefined )
1208+ | undefined
1209+ // A compiled process never suspends waiting for a terminal request: its
1210+ // active drain owns completion, while stop/failure either interrupts that
1211+ // owner or terminalizes an idle drain directly. An owner-local cell can
1212+ // therefore arbitrate the first request atomically without retaining a
1213+ // second Deferred in every compiled machine.
1214+ const requestRuntimeTermination = ( requested : ProcessTermination ) : Effect . Effect < boolean > =>
1215+ Effect . sync ( ( ) => {
1216+ if ( requestedTermination !== undefined ) {
1217+ return false
1218+ }
1219+ requestedTermination = requested
1220+ reservedTerminationSnapshot = reserveRequestedTermination ?.( requested )
1221+ return true
1222+ } )
12081223 let sendEvent = compactMailbox !== undefined
12091224 ? ( event : Event ) : Effect . Effect < void , StoppedError > => Effect . sync ( ( ) => offerCompactMailbox ( compactMailbox , event ) )
12101225 : ( event : Event ) : Effect . Effect < void , StoppedError > =>
@@ -1408,26 +1423,6 @@ const startCompiledInternal: <
14081423 Effect . asVoid
14091424 )
14101425
1411- const reserveTerminalSnapshot = (
1412- f : (
1413- snapshot : Extract < RuntimeSnapshot < State , Error , Output > , { readonly status : "active" } >
1414- ) => RuntimeSnapshot < State , Error , Output >
1415- ) : Effect . Effect < RuntimeSnapshot < State , Error , Output > | undefined > =>
1416- Effect . sync ( ( ) => {
1417- const latest = MutableRef . get ( current )
1418- if ( latest . terminalizing || latest . snapshot . status !== "active" ) {
1419- return undefined
1420- }
1421- const reserved = {
1422- revision : latest . revision + 1 ,
1423- snapshot : f ( latest . snapshot ) ,
1424- terminalizing : true ,
1425- changes : latest . changes
1426- }
1427- MutableRef . set ( current , { ...latest , terminalizing : true } )
1428- return reserved . snapshot
1429- } )
1430-
14311426 const setAndPublishSnapshot = (
14321427 snapshot : RuntimeSnapshot < State , Error , Output >
14331428 ) : Effect . Effect < void > =>
@@ -1469,24 +1464,19 @@ const startCompiledInternal: <
14691464 )
14701465 }
14711466
1472- const reserveStoppedSnapshot = reserveTerminalSnapshot ( ( snapshot ) => ( {
1473- status : "stopped" ,
1474- state : snapshot . state
1475- } ) )
1476-
1477- const reserveFailureSnapshot = ( cause : Cause . Cause < Error > ) =>
1478- reserveTerminalSnapshot ( ( snapshot ) => ( {
1479- status : "error" ,
1480- state : snapshot . state ,
1481- cause
1482- } ) )
1483-
1484- const reserveSuccessSnapshot = ( output : Output ) =>
1485- reserveTerminalSnapshot ( ( snapshot ) => ( {
1486- status : "done" ,
1487- state : snapshot . state ,
1488- output
1489- } ) )
1467+ reserveRequestedTermination = ( termination ) => {
1468+ const latest = MutableRef . get ( current )
1469+ if ( latest . terminalizing || latest . snapshot . status !== "active" ) {
1470+ return undefined
1471+ }
1472+ const snapshot : RuntimeSnapshot < State , Error , Output > = termination . _tag === "Stopped"
1473+ ? { status : "stopped" , state : latest . snapshot . state }
1474+ : termination . _tag === "Done"
1475+ ? { status : "done" , state : latest . snapshot . state , output : termination . output }
1476+ : { status : "error" , state : latest . snapshot . state , cause : termination . cause }
1477+ MutableRef . set ( current , { ...latest , terminalizing : true } )
1478+ return snapshot
1479+ }
14901480
14911481 const terminalizeReservedStop = (
14921482 snapshot : RuntimeSnapshot < State , Error , Output >
@@ -1515,16 +1505,8 @@ const startCompiledInternal: <
15151505 return terminalizeWith ( snapshot , exit , Deferred . succeed ( done , output ) )
15161506 }
15171507
1518- const reserveTermination = ( termination : ProcessTermination ) => {
1519- switch ( termination . _tag ) {
1520- case "Stopped" :
1521- return reserveStoppedSnapshot
1522- case "Done" :
1523- return reserveSuccessSnapshot ( termination . output )
1524- case "Failure" :
1525- return reserveFailureSnapshot ( termination . cause )
1526- }
1527- }
1508+ const reserveTermination = ( termination : ProcessTermination ) =>
1509+ Effect . sync ( ( ) => reserveRequestedTermination ! ( termination ) )
15281510
15291511 const completeTermination = (
15301512 termination : ProcessTermination ,
@@ -1540,24 +1522,6 @@ const startCompiledInternal: <
15401522 }
15411523 }
15421524
1543- let reservedTerminationSnapshot : RuntimeSnapshot < State , Error , Output > | undefined
1544- requestRuntimeTermination = ( requested ) =>
1545- Deferred . succeed ( termination , requested ) . pipe (
1546- Effect . flatMap ( ( accepted ) =>
1547- accepted
1548- ? reserveTermination ( requested ) . pipe (
1549- Effect . tap ( ( snapshot ) =>
1550- Effect . sync ( ( ) => {
1551- terminationRequested = true
1552- reservedTerminationSnapshot = snapshot
1553- } )
1554- ) ,
1555- Effect . as ( true )
1556- )
1557- : Effect . succeed ( false )
1558- )
1559- )
1560-
15611525 const finishRequestedTermination = ( requested : ProcessTermination ) : Effect . Effect < void > =>
15621526 Effect . gen ( function * ( ) {
15631527 const snapshot = reservedTerminationSnapshot ?? ( yield * reserveTermination ( requested ) )
@@ -1680,26 +1644,24 @@ const startCompiledInternal: <
16801644 Effect . gen ( function * ( ) {
16811645 let observedRevision = offerRevision
16821646 while ( true ) {
1683- const pending = yield * Deferred . poll ( termination )
1684- if ( Option . isSome ( pending ) ) {
1685- return yield * finishRequestedTermination ( yield * pending . value )
1647+ if ( requestedTermination !== undefined ) {
1648+ return yield * finishRequestedTermination ( requestedTermination )
16861649 }
16871650
16881651 const exit = yield * restore ( Effect . suspend ( ( ) => logic . drain ! ( context ) ) ) . pipe ( Effect . exit )
16891652 if ( Exit . isFailure ( exit ) ) {
16901653 const completed : ProcessTermination = { _tag : "Failure" , cause : exit . cause }
1691- yield * Deferred . succeed ( termination , completed )
1692- return yield * finishRequestedTermination ( yield * Deferred . await ( termination ) )
1654+ yield * requestRuntimeTermination ( completed )
1655+ return yield * finishRequestedTermination ( requestedTermination ! )
16931656 }
16941657 if ( Option . isSome ( exit . value ) ) {
16951658 const completed : ProcessTermination = { _tag : "Done" , output : exit . value . value }
1696- yield * Deferred . succeed ( termination , completed )
1697- return yield * finishRequestedTermination ( yield * Deferred . await ( termination ) )
1659+ yield * requestRuntimeTermination ( completed )
1660+ return yield * finishRequestedTermination ( requestedTermination ! )
16981661 }
16991662
1700- const requested = yield * Deferred . poll ( termination )
1701- if ( Option . isSome ( requested ) ) {
1702- return yield * finishRequestedTermination ( yield * requested . value )
1663+ if ( requestedTermination !== undefined ) {
1664+ return yield * finishRequestedTermination ( requestedTermination )
17031665 }
17041666
17051667 const continueDraining = yield * Effect . sync ( ( ) => {
@@ -1732,7 +1694,7 @@ const startCompiledInternal: <
17321694 sendEvent = ( event ) =>
17331695 Effect . uninterruptible (
17341696 Effect . suspend ( ( ) => {
1735- if ( compactMailbox ! . closed || terminationRequested ) {
1697+ if ( compactMailbox ! . closed || requestedTermination !== undefined ) {
17361698 return Effect . fail ( new StoppedError ( ) )
17371699 }
17381700 offerCompactMailbox ( compactMailbox ! , event )
@@ -1763,19 +1725,19 @@ const startCompiledInternal: <
17631725 return ref
17641726 }
17651727
1766- const pendingTermination = yield * Deferred . poll ( termination )
1728+ const pendingTermination = requestedTermination
17671729 const compiledRuntime : Effect . Effect < void , never , Requirements > = Effect . uninterruptibleMask ( ( restore ) =>
17681730 Effect . gen ( function * ( ) {
17691731 let requested : ProcessTermination
1770- if ( Option . isSome ( pendingTermination ) ) {
1771- requested = yield * pendingTermination . value
1732+ if ( pendingTermination !== undefined ) {
1733+ requested = pendingTermination
17721734 } else {
17731735 const exit = yield * restore ( Effect . suspend ( ( ) => logic . run ( context ) ) ) . pipe ( Effect . exit )
17741736 const completed : ProcessTermination = Exit . isFailure ( exit )
17751737 ? { _tag : "Failure" , cause : exit . cause }
17761738 : { _tag : "Done" , output : exit . value }
1777- yield * Deferred . succeed ( termination , completed )
1778- requested = yield * Deferred . await ( termination )
1739+ yield * requestRuntimeTermination ( completed )
1740+ requested = requestedTermination !
17791741 }
17801742
17811743 const snapshot = reservedTerminationSnapshot ?? ( yield * reserveTermination ( requested ) )
0 commit comments