Skip to content

Commit ba095f2

Browse files
Clarify compiled process lifecycle
1 parent e830c66 commit ba095f2

5 files changed

Lines changed: 389 additions & 251 deletions

File tree

.changeset/steady-runtimes-flow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@typeonce/effect-machine": patch
3+
---
4+
5+
Replace implicit compiled-process capability markers with one typed execution descriptor, make lifecycle states explicit, and centralize snapshot publication at Effect boundaries.

perf/runtime/counter.mjs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,28 @@ const rawProcessLogic = {
444444
run: () => Effect.never
445445
}
446446

447-
const rawCompiledProcessLogic = {
448-
[machineRuntime.compiledProcess]: true,
449-
initial: () => Effect.succeed(0),
450-
run: () => Effect.never,
451-
drain: () => Effect.succeed(Option.none())
452-
}
447+
// The head harness benchmarks both the base and head builds. Keep the fixture
448+
// bilingual across the protocol migration so both sides are forced through
449+
// their compact runtime rather than silently comparing different strategies.
450+
const rawCompiledProcessLogic = machineRuntime.compiledProcess === undefined
451+
? {
452+
execution: {
453+
_tag: "Compiled",
454+
childless: false,
455+
drain: {
456+
_tag: "Process",
457+
run: () => Effect.succeed(Option.none())
458+
}
459+
},
460+
initial: () => Effect.succeed(0),
461+
run: () => Effect.never
462+
}
463+
: {
464+
[machineRuntime.compiledProcess]: true,
465+
initial: () => Effect.succeed(0),
466+
run: () => Effect.never,
467+
drain: () => Effect.succeed(Option.none())
468+
}
453469

454470
const startRawProcesses = (count) =>
455471
Effect.runPromise(
@@ -464,7 +480,7 @@ const startCompiledRawProcesses = (count) =>
464480
Effect.runPromise(
465481
Effect.forEach(
466482
Array.from({ length: count }),
467-
() => machineRuntime.startProcess(rawCompiledProcessLogic),
483+
() => machineRuntime.startProcessWithStrategyForTesting(rawCompiledProcessLogic, "compiled"),
468484
{ concurrency: 1 }
469485
)
470486
)

src/internal/machine/process.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,18 @@ const makeChildlessCompiledDrain = (
229229
}
230230
const commitAndContinue = (): Effect.Effect<Option.Option<any>, any, any> => {
231231
const notification = commit()
232-
if (notification !== undefined || afterCommit !== undefined) {
233-
context.flush()
234-
}
235232
const continued = continueAfterCommit()
236-
return notification === undefined ? continued : notification.pipe(Effect.andThen(continued))
233+
const effect = notification === undefined ? continued : notification.pipe(Effect.andThen(continued))
234+
return notification === undefined && afterCommit === undefined
235+
? effect
236+
: context.runAfterChanges(effect)
237237
}
238238

239239
if (beforeCommit === undefined) {
240240
return commitAndContinue()
241241
}
242-
context.flush()
243-
return beforeCommit.pipe(
244-
Effect.andThen(Effect.suspend(commitAndContinue))
242+
return context.runAfterChanges(
243+
beforeCommit.pipe(Effect.andThen(Effect.suspend(commitAndContinue)))
245244
)
246245
})
247246
return internalRuntime.provideMachineRuntime(loop, context.scope)
@@ -444,18 +443,17 @@ const makeInvokingCompiledDrain = (
444443
}
445444
const commitAndContinue = (): Effect.Effect<Option.Option<any>, any, any> => {
446445
const notification = commit()
447-
if (notification !== undefined || afterCommit.length > 0) {
448-
context.flush()
449-
}
450446
const continued = continueAfterCommit()
451-
return notification === undefined ? continued : notification.pipe(Effect.andThen(continued))
447+
const effect = notification === undefined ? continued : notification.pipe(Effect.andThen(continued))
448+
return notification === undefined && afterCommit.length === 0
449+
? effect
450+
: context.runAfterChanges(effect)
452451
}
453452
if (beforeCommit.length === 0) {
454453
return commitAndContinue()
455454
}
456-
context.flush()
457-
return runSequentialDiscard(beforeCommit).pipe(
458-
Effect.andThen(Effect.suspend(commitAndContinue))
455+
return context.runAfterChanges(
456+
runSequentialDiscard(beforeCommit).pipe(Effect.andThen(Effect.suspend(commitAndContinue)))
459457
)
460458
})
461459

@@ -590,13 +588,18 @@ const makeProcessLogic: <
590588
)
591589
: Effect.try({ try: makeCompiledInitial!, catch: (error) => error as any })
592590
return ({
593-
[internalRuntime.childlessProcess]: hasInvokes ? undefined : true,
594-
[internalRuntime.compiledProcess]: true,
595-
[internalRuntime.compiledProcessInitial]: entry._tag === "Initial" ? makeInitial : undefined,
596-
[internalRuntime.compiledProcessInitialSync]: makeCompiledInitial,
597-
[internalRuntime.compiledProcessDrain]: hasInvokes
598-
? makeInvokingCompiledDrain(machine, entry._tag === "Resume")
599-
: makeChildlessCompiledDrain(machine, entry._tag === "Resume"),
591+
execution: {
592+
_tag: "Compiled",
593+
childless: !hasInvokes,
594+
initial: entry._tag === "Initial" ? makeInitial : undefined,
595+
initialSync: makeCompiledInitial,
596+
drain: {
597+
_tag: "Owned",
598+
run: hasInvokes
599+
? makeInvokingCompiledDrain(machine, entry._tag === "Resume")
600+
: makeChildlessCompiledDrain(machine, entry._tag === "Resume")
601+
}
602+
},
600603
initial: (scope) =>
601604
entry._tag === "Resume"
602605
? internalRuntime.provideMachineRuntime(Serialization.normalizeSnapshotEffect(machine, entry.snapshot), scope)

0 commit comments

Comments
 (0)