One app process for the length of one main, the same for every platform:
builds the process, starts it, runs main with the first screen and closes
the process when main ends — on success, on failure and when interrupted.
Nothing is built, and so nothing is sent, before the call. The process owns a
ManagedRuntime, so no Scope appears in a signature; its handles live as
long as main does.
Resolves with main's result. A typed failure of the start or of main
rejects with the very same tagged error object; so does the stop of a
challenge the call's otherwise could not settle (OtherwiseDispatchStop,
read back into the call's typed failure); a defect rejects with the defect;
an aborted signal interrupts main and rejects with the abort reason.
The process's own end stops the call. The start and main are raced
against the process's end (AppProcessReference.ended, from the process's
reference): a session-fatal answer to a background request, or a tail
request whose challenge the branches could not settle, ends the process, so
a still-running main is interrupted and the call rejects with that same
typed failure.
The launch's tail outlives main. The launch hands the part it keeps
sending after the feed is on screen to the process's background fibers
(MobileProcessBackground), so main may be one short request while the
rest of the launch still goes out. After main — whether it succeeded or
failed — the run waits for every one of those fibers before the app closes,
so the tail is sent in full. The call's outcome is then chosen in one place
(outcomeOf), from what main left, what the tail left and whether the
call was aborted:
an abort — before, during or after the wait — rejects with the abort reason;
a failed main rejects with main's own error, unchanged (the run never
mutates it); what the background left besides is composed into the run's
Cause in parallel with main's and logged with Effect.logError
carrying that cause, never silent;
a successful main with a process that ended itself rejects with the
failure it ended with, even if main had already returned (the process's
endedBy, read after the wait — a fact, not a race);
a successful main with another failure of the wait rejects with it (a
defect stays a defect), after every other fiber of the tail finished.
The launch had already handed main its screen, so a tail failure belongs to
the call's own await, not to main's channel.
One app process for the length of one
main, the same for every platform: builds the process, starts it, runsmainwith the first screen and closes the process whenmainends — on success, on failure and when interrupted. Nothing is built, and so nothing is sent, before the call. The process owns aManagedRuntime, so noScopeappears in a signature; its handles live as long asmaindoes.Resolves with
main's result. A typed failure of the start or ofmainrejects with the very same tagged error object; so does the stop of a challenge the call'sotherwisecould not settle (OtherwiseDispatchStop, read back into the call's typed failure); a defect rejects with the defect; an abortedsignalinterruptsmainand rejects with the abort reason.The process's own end stops the call. The start and
mainare raced against the process's end (AppProcessReference.ended, from the process's reference): a session-fatal answer to a background request, or a tail request whose challenge the branches could not settle, ends the process, so a still-runningmainis interrupted and the call rejects with that same typed failure.The launch's tail outlives
main. The launch hands the part it keeps sending after the feed is on screen to the process's background fibers (MobileProcessBackground), somainmay be one short request while the rest of the launch still goes out. Aftermain— whether it succeeded or failed — the run waits for every one of those fibers before the app closes, so the tail is sent in full. The call's outcome is then chosen in one place (outcomeOf), from whatmainleft, what the tail left and whether the call was aborted:mainrejects withmain's own error, unchanged (the run never mutates it); what the background left besides is composed into the run'sCausein parallel withmain's and logged withEffect.logErrorcarrying that cause, never silent;mainwith a process that ended itself rejects with the failure it ended with, even ifmainhad already returned (the process'sendedBy, read after the wait — a fact, not a race);mainwith another failure of the wait rejects with it (a defect stays a defect), after every other fiber of the tail finished.The launch had already handed
mainits screen, so a tail failure belongs to the call's ownawait, not tomain's channel.