wasm: one IPN per runtime with an explicit readiness handshake #20
@@ -27,15 +27,29 @@ export async function startIPN(
|
||||
})
|
||||
|
||||
go.env[INIT_CALLBACK_ENV] = name
|
||||
const exited = go.run(instance).then(() => {
|
||||
|
||||
// An exit before the IPN reaches the caller is a startup failure, and throwing
|
||||
// hands it back as a rejection. Afterwards the caller holds the only shutdown
|
||||
// path, so an exit is either that shutdown or a panic; report it either way,
|
||||
// because the IPN is dead in both cases.
|
||||
let handedOver = false
|
||||
const exited: Promise<never> = go.run(instance).then(() => {
|
||||
delete globals[name]
|
||||
onExit("Unexpected shutdown")
|
||||
throw new Error("Go runtime exited before the IPN was ready")
|
||||
if (handedOver) onExit("Go runtime exited")
|
||||
// Always reject: before the handover this is what fails the race below,
|
||||
// and after it the race has settled, so nothing observes the rejection.
|
||||
throw new Error(
|
||||
handedOver
|
||||
? "Go runtime exited"
|
||||
: "Go runtime exited before the IPN was ready"
|
||||
)
|
||||
})
|
||||
|
||||
const [newIPN, terminate] = await Promise.race([ready, exited])
|
||||
try {
|
||||
return await newIPN(config)
|
||||
const ipn = await newIPN(config)
|
||||
handedOver = true
|
||||
return ipn
|
||||
} catch (err) {
|
||||
// Nothing was built, so nothing can shut the runtime down. Exit it here and
|
||||
// wait for it, or the page keeps a blocked runtime for a failed startup.
|
||||
|
||||
Reference in New Issue
Block a user