@hew-lang/sandbox-vm 0.7.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interpreter/v1/exec.js +182 -8
- package/dist/interpreter/v1/instructions.generated.d.ts +2 -1
- package/dist/interpreter/v1/package-validator.generated.js +1507 -1315
- package/dist/interpreter/v1/semaphores.d.ts +39 -0
- package/dist/interpreter/v1/semaphores.js +109 -0
- package/dist/interpreter/v1/shims.d.ts +19 -1
- package/dist/interpreter/v1/shims.js +52 -13
- package/dist/interpreter/v1/validate.js +2 -1
- package/dist/interpreter/values.d.ts +1 -1
- package/dist/interpreter/values.js +8 -0
- package/package.json +4 -4
|
@@ -16,6 +16,7 @@ import { StructuralRenderer } from "./structural.js";
|
|
|
16
16
|
import { timestampBinary } from "./timestamp.js";
|
|
17
17
|
import { selectedValue, collectionOperation, sharedOperation, } from "./value-operations.js";
|
|
18
18
|
import { Pipes } from "./pipes.js";
|
|
19
|
+
import { Semaphores } from "./semaphores.js";
|
|
19
20
|
import { FrameScheduler } from "./scheduler.js";
|
|
20
21
|
import { DeterministicIds } from "../../scheduler/ids.js";
|
|
21
22
|
import { Mt19937 } from "./mt19937.js";
|
|
@@ -128,6 +129,7 @@ class ExecutorV1 {
|
|
|
128
129
|
rootFault = null;
|
|
129
130
|
pkg;
|
|
130
131
|
directories;
|
|
132
|
+
semaphores;
|
|
131
133
|
constructor(admission, trace, stdin, policy, options) {
|
|
132
134
|
this.trace = trace;
|
|
133
135
|
this.stdin = stdin;
|
|
@@ -136,10 +138,16 @@ class ExecutorV1 {
|
|
|
136
138
|
this.pkg = pkg;
|
|
137
139
|
this.directories = new BrowserDirectories(options.directoryRoots);
|
|
138
140
|
this.scheduler = new FrameScheduler(trace, policy);
|
|
141
|
+
this.semaphores = new Semaphores((nanos, ready) => this.scheduler.after(nanos, ready));
|
|
139
142
|
this.ids = new DeterministicIds(trace.replay.seed);
|
|
140
143
|
this.host = {
|
|
141
144
|
argv: [...(options.argv ?? ["main.hew"])],
|
|
142
145
|
unixTimeMillis: () => this.trace.virtualTimeMs,
|
|
146
|
+
monotonicTimeNanos: () => {
|
|
147
|
+
const millis = this.trace.virtualTimeMs;
|
|
148
|
+
return (BigInt(Math.trunc(millis)) * 1000000n +
|
|
149
|
+
BigInt(Math.round((millis % 1) * 1_000_000)));
|
|
150
|
+
},
|
|
143
151
|
calendarBridge: options.calendarBridge,
|
|
144
152
|
codecBridge: options.codecBridge,
|
|
145
153
|
encodingError: (format, message) => {
|
|
@@ -151,6 +159,10 @@ class ExecutorV1 {
|
|
|
151
159
|
errors[format] = message;
|
|
152
160
|
return errors[format] ?? "";
|
|
153
161
|
},
|
|
162
|
+
setFileError: (message) => {
|
|
163
|
+
this.current.context.fileError =
|
|
164
|
+
message === null ? null : { kind: 0, message };
|
|
165
|
+
},
|
|
154
166
|
fileError: (operation) => {
|
|
155
167
|
const error = this.current.context.fileError;
|
|
156
168
|
switch (operation) {
|
|
@@ -168,6 +180,7 @@ class ExecutorV1 {
|
|
|
168
180
|
}
|
|
169
181
|
},
|
|
170
182
|
pipes: this.pipes,
|
|
183
|
+
semaphores: this.semaphores,
|
|
171
184
|
generatorStream: (value) => {
|
|
172
185
|
const id = this.ids.channel();
|
|
173
186
|
this.generatorStreams.set(id, {
|
|
@@ -1158,7 +1171,15 @@ class ExecutorV1 {
|
|
|
1158
1171
|
// `self`. A plain function value carries none.
|
|
1159
1172
|
const callee = this.boundary(act, term.callee);
|
|
1160
1173
|
const args = term.args.map((operand) => this.boundary(act, operand));
|
|
1161
|
-
|
|
1174
|
+
const body = this.functionAt(calleeFunction(callee, term.specialization));
|
|
1175
|
+
this.current = this.activate(body, callee.kind === "closure" ? [callee.environment, ...args] : args, act, term.result, term.normal, term.unwind);
|
|
1176
|
+
// SIR already distinguishes a consuming body from a borrowed body
|
|
1177
|
+
// exposed through a once-callable view. Only the latter leaves its
|
|
1178
|
+
// receiver cleanup to this invocation boundary.
|
|
1179
|
+
if (callee.kind === "closure" &&
|
|
1180
|
+
term.callee.decision === "move" &&
|
|
1181
|
+
body.params[0]?.own !== "owned")
|
|
1182
|
+
this.current.consumedCallable = callee;
|
|
1162
1183
|
return;
|
|
1163
1184
|
}
|
|
1164
1185
|
case "actor.call":
|
|
@@ -1176,6 +1197,23 @@ class ExecutorV1 {
|
|
|
1176
1197
|
if (registration.kind === "refused")
|
|
1177
1198
|
throw new Error(`runtime family ${registration.capability} was refused after admission`);
|
|
1178
1199
|
switch (registration.handler) {
|
|
1200
|
+
case "context_actor_id":
|
|
1201
|
+
this.completeShim(act, term, {
|
|
1202
|
+
kind: "i64",
|
|
1203
|
+
value: act.context.actor?.identity ?? 0n,
|
|
1204
|
+
});
|
|
1205
|
+
return;
|
|
1206
|
+
case "context_supervisor": {
|
|
1207
|
+
const parent = act.context.actor?.supervisor?.owner;
|
|
1208
|
+
this.completeShim(act, term, parent
|
|
1209
|
+
? { kind: "supervisor", id: parent.id }
|
|
1210
|
+
: { kind: "i64", value: 0n });
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
case "context_trace_span":
|
|
1214
|
+
// The sandbox installs no external tracing span in actor turns.
|
|
1215
|
+
this.completeShim(act, term, { kind: "i64", value: 0n });
|
|
1216
|
+
return;
|
|
1179
1217
|
case "actor_caller": {
|
|
1180
1218
|
const caller = act.context.caller ?? { kind: "Task" };
|
|
1181
1219
|
const payload = [];
|
|
@@ -1679,6 +1717,8 @@ class ExecutorV1 {
|
|
|
1679
1717
|
return true;
|
|
1680
1718
|
}
|
|
1681
1719
|
returnFrom(act, value) {
|
|
1720
|
+
if (this.finishConsumedCallable(act, value, () => this.returnFrom(act, value)))
|
|
1721
|
+
return;
|
|
1682
1722
|
if (this.finishConstruction(act, () => this.returnFrom(act, value)))
|
|
1683
1723
|
return;
|
|
1684
1724
|
const caller = act.caller;
|
|
@@ -1740,6 +1780,8 @@ class ExecutorV1 {
|
|
|
1740
1780
|
this.takeEdge(act, unwind);
|
|
1741
1781
|
}
|
|
1742
1782
|
resumeUnwind(act, handback) {
|
|
1783
|
+
if (this.finishConsumedCallable(act, null, () => this.resumeUnwind(act, handback)))
|
|
1784
|
+
return;
|
|
1743
1785
|
if (this.finishConstruction(act, () => this.resumeUnwind(act, handback)))
|
|
1744
1786
|
return;
|
|
1745
1787
|
const fault = act.fault;
|
|
@@ -1770,6 +1812,34 @@ class ExecutorV1 {
|
|
|
1770
1812
|
this.current = caller;
|
|
1771
1813
|
this.takeEdge(caller, act.unwind);
|
|
1772
1814
|
}
|
|
1815
|
+
finishConsumedCallable(act, value, done) {
|
|
1816
|
+
const callable = act.consumedCallable;
|
|
1817
|
+
if (!callable)
|
|
1818
|
+
return false;
|
|
1819
|
+
act.consumedCallable = undefined;
|
|
1820
|
+
this.running = false;
|
|
1821
|
+
this.closeValueAsync(callable, this.faultText(act.fault), (fault) => {
|
|
1822
|
+
act.fault = combineFaults(act.fault, fault);
|
|
1823
|
+
const resume = () => {
|
|
1824
|
+
if (value !== null && act.fault)
|
|
1825
|
+
this.resumeUnwind(act, null);
|
|
1826
|
+
else
|
|
1827
|
+
done();
|
|
1828
|
+
const current = this.current;
|
|
1829
|
+
this.scheduler.enqueue(current.context.id, () => this.runFrame(current));
|
|
1830
|
+
};
|
|
1831
|
+
// A successful body result is not observable until receiver cleanup
|
|
1832
|
+
// succeeds. A cleanup fault must release that unpublished result.
|
|
1833
|
+
if (value !== null && act.fault)
|
|
1834
|
+
this.closeValueAsync(value, this.faultText(act.fault), (resultFault) => {
|
|
1835
|
+
act.fault = combineFaults(act.fault, resultFault);
|
|
1836
|
+
resume();
|
|
1837
|
+
}, act.context.actor, act.rcOwner);
|
|
1838
|
+
else
|
|
1839
|
+
resume();
|
|
1840
|
+
}, act.context.actor, act.rcOwner);
|
|
1841
|
+
return true;
|
|
1842
|
+
}
|
|
1773
1843
|
suspend(act, input) {
|
|
1774
1844
|
const registration = resolveSuspension(input);
|
|
1775
1845
|
if (registration.kind === "refused")
|
|
@@ -2042,6 +2112,7 @@ class ExecutorV1 {
|
|
|
2042
2112
|
// The record is the raw line,
|
|
2043
2113
|
// so the records concatenate to the stdin the program consumed.
|
|
2044
2114
|
const line = this.stdin.readLine() ?? new Uint8Array();
|
|
2115
|
+
act.context.fileError = null;
|
|
2045
2116
|
this.trace.recordReplayInput({ kind: "stdin", data: new TextDecoder().decode(line) }, false);
|
|
2046
2117
|
this.park(act, term)(bytesValue([...line]));
|
|
2047
2118
|
return;
|
|
@@ -2080,6 +2151,25 @@ class ExecutorV1 {
|
|
|
2080
2151
|
}
|
|
2081
2152
|
return;
|
|
2082
2153
|
}
|
|
2154
|
+
case "SemaphoreAcquire": {
|
|
2155
|
+
const handle = this.boundary(act, term.inputs[0]);
|
|
2156
|
+
const timeout = term.detail.operation === "AcquireTimeout"
|
|
2157
|
+
? this.boundary(act, term.inputs[1])
|
|
2158
|
+
: null;
|
|
2159
|
+
if (timeout !== null && timeout.kind !== "i64")
|
|
2160
|
+
throw new Error("semaphore timeout must be an integer");
|
|
2161
|
+
let operation;
|
|
2162
|
+
const wake = this.park(act, term, () => { }, () => operation?.take());
|
|
2163
|
+
operation = this.semaphores.acquire(handle, timeout?.value ?? null, (acquired) => {
|
|
2164
|
+
wake(timeout === null ? UNIT : { kind: "bool", value: acquired });
|
|
2165
|
+
});
|
|
2166
|
+
const cancel = act.context.cancel;
|
|
2167
|
+
act.context.cancel = (fault) => {
|
|
2168
|
+
operation?.cancel();
|
|
2169
|
+
cancel?.(fault);
|
|
2170
|
+
};
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2083
2173
|
case "Sleep": {
|
|
2084
2174
|
const duration = term.inputs[0]
|
|
2085
2175
|
? this.boundary(act, term.inputs[0])
|
|
@@ -2113,7 +2203,7 @@ class ExecutorV1 {
|
|
|
2113
2203
|
message: `local actor wait cycle at ${operation}: ${path.map((actor) => actor.identity).join(" -> ")}`,
|
|
2114
2204
|
});
|
|
2115
2205
|
}
|
|
2116
|
-
park(act, term, cleanup = () => { }) {
|
|
2206
|
+
park(act, term, cleanup = () => { }, accepted = () => { }) {
|
|
2117
2207
|
this.running = false;
|
|
2118
2208
|
act.context.parked = true;
|
|
2119
2209
|
let pending = null;
|
|
@@ -2138,6 +2228,7 @@ class ExecutorV1 {
|
|
|
2138
2228
|
: term.unwind);
|
|
2139
2229
|
}
|
|
2140
2230
|
else {
|
|
2231
|
+
accepted();
|
|
2141
2232
|
if (term.result && term.result !== "never")
|
|
2142
2233
|
this.define(act, term.result.value, outcome.value);
|
|
2143
2234
|
const edge = term.resumes[outcome.edge];
|
|
@@ -2480,6 +2571,9 @@ class ExecutorV1 {
|
|
|
2480
2571
|
value.cell.weak -= 1;
|
|
2481
2572
|
}
|
|
2482
2573
|
break;
|
|
2574
|
+
case "semaphore":
|
|
2575
|
+
this.semaphores.close(value);
|
|
2576
|
+
break;
|
|
2483
2577
|
case "host_resource": {
|
|
2484
2578
|
if (value.owner.closed)
|
|
2485
2579
|
break;
|
|
@@ -3114,12 +3208,29 @@ class ExecutorV1 {
|
|
|
3114
3208
|
const count = isPool ? args[args.length - 1] : undefined;
|
|
3115
3209
|
if (isPool && count?.kind !== "i64")
|
|
3116
3210
|
throw new Error("pool construction has no count");
|
|
3117
|
-
const
|
|
3118
|
-
|
|
3119
|
-
|
|
3211
|
+
const configured = isPool ? args.slice(0, -1) : args;
|
|
3212
|
+
const initial = layout.backoff
|
|
3213
|
+
? configured[configured.length - 2]
|
|
3214
|
+
: undefined;
|
|
3215
|
+
const maximum = layout.backoff
|
|
3216
|
+
? configured[configured.length - 1]
|
|
3217
|
+
: undefined;
|
|
3218
|
+
const backoff = initial?.kind === "i64" && maximum?.kind === "i64"
|
|
3219
|
+
? { initial: initial.value, maximum: maximum.value }
|
|
3220
|
+
: null;
|
|
3221
|
+
const validBackoff = !layout.backoff ||
|
|
3222
|
+
(backoff !== null &&
|
|
3223
|
+
backoff.initial > 0n &&
|
|
3224
|
+
backoff.maximum >= backoff.initial);
|
|
3225
|
+
const config = layout.backoff ? configured.slice(0, -2) : configured;
|
|
3226
|
+
if (!validBackoff ||
|
|
3227
|
+
(count?.kind === "i64" &&
|
|
3228
|
+
(count.value <= 0n || count.value > 2147483647n))) {
|
|
3120
3229
|
const fault = {
|
|
3121
3230
|
kind: "panic",
|
|
3122
|
-
message:
|
|
3231
|
+
message: !validBackoff
|
|
3232
|
+
? "supervisor backoff requires positive initial and maximum >= initial"
|
|
3233
|
+
: "supervisor pool count must be between 1 and 2147483647",
|
|
3123
3234
|
};
|
|
3124
3235
|
this.running = false;
|
|
3125
3236
|
this.closeValueAsync({ kind: "record", typeId: "", fields: config }, fault.message, (closeFault) => {
|
|
@@ -3147,6 +3258,9 @@ class ExecutorV1 {
|
|
|
3147
3258
|
teardownChild: null,
|
|
3148
3259
|
teardownCancelTimer: null,
|
|
3149
3260
|
restartTimes: [],
|
|
3261
|
+
backoff,
|
|
3262
|
+
restartDelays: new Map(),
|
|
3263
|
+
restartTimers: new Map(),
|
|
3150
3264
|
closed: [],
|
|
3151
3265
|
};
|
|
3152
3266
|
this.supervisors.set(owner.id, owner);
|
|
@@ -3628,6 +3742,30 @@ class ExecutorV1 {
|
|
|
3628
3742
|
for (const timer of [...actor.timers])
|
|
3629
3743
|
timer.cancel();
|
|
3630
3744
|
}
|
|
3745
|
+
bindActorStream(context, sink) {
|
|
3746
|
+
let unwatch = () => { };
|
|
3747
|
+
let active = true;
|
|
3748
|
+
const detach = () => {
|
|
3749
|
+
active = false;
|
|
3750
|
+
unwatch();
|
|
3751
|
+
};
|
|
3752
|
+
const closed = () => {
|
|
3753
|
+
if (!active || !this.pipes.peerClosed(sink))
|
|
3754
|
+
return;
|
|
3755
|
+
// Bind the reader to this exact producer turn, including while it waits
|
|
3756
|
+
// on another operation. Later reader closes must not cancel a new turn.
|
|
3757
|
+
detach();
|
|
3758
|
+
context.pendingCancellation ??= {
|
|
3759
|
+
kind: "panic",
|
|
3760
|
+
message: "actor stream reader closed",
|
|
3761
|
+
cancelled: true,
|
|
3762
|
+
};
|
|
3763
|
+
context.cancel?.(context.pendingCancellation);
|
|
3764
|
+
};
|
|
3765
|
+
unwatch = this.pipes.observe(sink, closed);
|
|
3766
|
+
closed();
|
|
3767
|
+
return detach;
|
|
3768
|
+
}
|
|
3631
3769
|
dispatchActor(actor) {
|
|
3632
3770
|
if (actor.busy || !actor.alive || actor.drainingMailbox)
|
|
3633
3771
|
return;
|
|
@@ -3696,6 +3834,7 @@ class ExecutorV1 {
|
|
|
3696
3834
|
actor_id: actor.id,
|
|
3697
3835
|
handler: message.handler.name,
|
|
3698
3836
|
});
|
|
3837
|
+
let unwatchStream = () => { };
|
|
3699
3838
|
const frame = this.activate(this.functionAt(message.handler.callable), [actor.state, ...message.payload], null, null, undefined, null, {
|
|
3700
3839
|
id: actor.id,
|
|
3701
3840
|
actor,
|
|
@@ -3703,6 +3842,7 @@ class ExecutorV1 {
|
|
|
3703
3842
|
requestDeadline: message.requestDeadline,
|
|
3704
3843
|
reply: message.reply,
|
|
3705
3844
|
returned: (value) => {
|
|
3845
|
+
unwatchStream();
|
|
3706
3846
|
actor.active = null;
|
|
3707
3847
|
const drained = (fault) => {
|
|
3708
3848
|
actor.busy = false;
|
|
@@ -3738,6 +3878,7 @@ class ExecutorV1 {
|
|
|
3738
3878
|
}
|
|
3739
3879
|
},
|
|
3740
3880
|
failed: (fault) => {
|
|
3881
|
+
unwatchStream();
|
|
3741
3882
|
actor.active = null;
|
|
3742
3883
|
actor.busy = false;
|
|
3743
3884
|
if (fault.kind === "trap" &&
|
|
@@ -3758,6 +3899,13 @@ class ExecutorV1 {
|
|
|
3758
3899
|
},
|
|
3759
3900
|
});
|
|
3760
3901
|
actor.active = frame.context;
|
|
3902
|
+
if (message.handler.streams) {
|
|
3903
|
+
// StreamStart's checked producer protocol appends its output sink.
|
|
3904
|
+
const sink = message.payload.at(-1);
|
|
3905
|
+
if (sink?.kind !== "sink")
|
|
3906
|
+
throw new Error("actor stream producer has no final sink");
|
|
3907
|
+
unwatchStream = this.bindActorStream(frame.context, sink);
|
|
3908
|
+
}
|
|
3761
3909
|
this.runFrame(frame);
|
|
3762
3910
|
});
|
|
3763
3911
|
}
|
|
@@ -4011,7 +4159,7 @@ class ExecutorV1 {
|
|
|
4011
4159
|
wake();
|
|
4012
4160
|
}
|
|
4013
4161
|
}
|
|
4014
|
-
restartChild(owner, child, debts) {
|
|
4162
|
+
restartChild(owner, child, debts, delayElapsed = false) {
|
|
4015
4163
|
if (!owner.alive ||
|
|
4016
4164
|
owner.specs[child].restart === "temporary" ||
|
|
4017
4165
|
owner.spent.has(child)) {
|
|
@@ -4025,6 +4173,24 @@ class ExecutorV1 {
|
|
|
4025
4173
|
return;
|
|
4026
4174
|
}
|
|
4027
4175
|
const now = this.trace.virtualTimeMs;
|
|
4176
|
+
if (owner.backoff && debts.length > 0 && !delayElapsed) {
|
|
4177
|
+
const previous = owner.restartDelays.get(child);
|
|
4178
|
+
const healthy = previous?.publishedAt != null &&
|
|
4179
|
+
now - previous.publishedAt >= owner.layout.window_secs * 1000;
|
|
4180
|
+
const doubled = previous ? previous.delay * 2n : owner.backoff.initial;
|
|
4181
|
+
const delay = !previous || healthy
|
|
4182
|
+
? owner.backoff.initial
|
|
4183
|
+
: doubled < owner.backoff.maximum
|
|
4184
|
+
? doubled
|
|
4185
|
+
: owner.backoff.maximum;
|
|
4186
|
+
owner.restartDelays.set(child, { delay, publishedAt: null });
|
|
4187
|
+
owner.recovering.add(child);
|
|
4188
|
+
owner.restartTimers.set(child, this.scheduler.after(delay, () => {
|
|
4189
|
+
owner.restartTimers.delete(child);
|
|
4190
|
+
this.restartChild(owner, child, debts, true);
|
|
4191
|
+
}));
|
|
4192
|
+
return;
|
|
4193
|
+
}
|
|
4028
4194
|
owner.restartTimes = owner.restartTimes.filter((at) => now - at < owner.layout.window_secs * 1000);
|
|
4029
4195
|
if (owner.restartTimes.length >= owner.layout.max_restarts) {
|
|
4030
4196
|
this.escalateSupervisor(owner, debts);
|
|
@@ -4079,7 +4245,12 @@ class ExecutorV1 {
|
|
|
4079
4245
|
this.restartChild(owner, pending.child, pending.debts);
|
|
4080
4246
|
return;
|
|
4081
4247
|
}
|
|
4082
|
-
this.startChild(owner, index,
|
|
4248
|
+
this.startChild(owner, index, () => {
|
|
4249
|
+
const delay = owner.restartDelays.get(index);
|
|
4250
|
+
if (delay)
|
|
4251
|
+
delay.publishedAt = this.trace.virtualTimeMs;
|
|
4252
|
+
start();
|
|
4253
|
+
}, () => {
|
|
4083
4254
|
owner.restartBusy = false;
|
|
4084
4255
|
this.restartChild(owner, index, debts);
|
|
4085
4256
|
});
|
|
@@ -4155,6 +4326,9 @@ class ExecutorV1 {
|
|
|
4155
4326
|
if (!owner.alive)
|
|
4156
4327
|
return;
|
|
4157
4328
|
owner.alive = false;
|
|
4329
|
+
for (const cancel of owner.restartTimers.values())
|
|
4330
|
+
cancel();
|
|
4331
|
+
owner.restartTimers.clear();
|
|
4158
4332
|
if (owner.constructor) {
|
|
4159
4333
|
owner.constructor.pendingCancellation ??= {
|
|
4160
4334
|
kind: "panic",
|
|
@@ -659,7 +659,7 @@ export type RuntimeCallFamily = {
|
|
|
659
659
|
format: EncodingFormat;
|
|
660
660
|
op: EncodingOp;
|
|
661
661
|
};
|
|
662
|
-
} | "ActorDemonitor" | "ActorLink" | "ActorMonitor" | "ActorCaller" | "ActorRefusalLog" | "ActorUnlink" | "AutoMutexAlloc" | "AutoMutexFree" | "AutoMutexLock" | "AutoMutexUnlock" | "DequePopFront" | "DequePopBack" | "BytesAppend" | "BytesClear" | "BytesConcat" | "BytesContains" | "BytesDecodeUtf8" | "BytesDecodeUtf8Lossy" | "BytesEndsWith" | "BytesGet" | "BytesIndex" | "BytesIsEmpty" | "BytesLen" | "BytesPop" | "BytesPush" | "BytesSet" | "BytesSlice" | "BytesSliceFrom" | "BytesStartsWith" | "BytesNew" | "CancelTokenIsRequested" | "CancelTokenRelease" | "CancelTokenRetain" | "ActorRequestRelease" | "ActorCallFree" | "ActorRequestTake" | "DurationAbs" | "DurationHours" | "DurationIsZero" | "DurationMicros" | "DurationMillis" | "DurationMins" | "DurationNanos" | "DurationSecs" | "DynBoxAlloc" | "DynBoxFree" | "HashMapContainsKeyLayout" | "HashMapClearLayout" | "HashMapCloneLayout" | "HashMapEntriesLayout" | "HashMapFreeLayout" | "HashMapGetLayout" | "HashMapInsertLayout" | "HashMapKeysLayout" | "HashMapLenLayout" | "HashMapNew" | "HashMapNewWithLayout" | "HashMapRemoveLayout" | "HashMapValuesLayout" | "HashSetContainsLayout" | "HashSetClearLayout" | "HashSetCloneLayout" | "HashSetFreeLayout" | "HashSetInsertLayout" | "HashSetIsEmptyLayout" | "HashSetLenLayout" | "HashSetNew" | "HashSetNewWithLayout" | "HashSetRemoveLayout" | "HashSetToVecLayout" | "InstantDurationSince" | "InstantElapsed" | "InstantNow" | "TimestampNow" | {
|
|
662
|
+
} | "ActorDemonitor" | "ActorLink" | "ActorMonitor" | "ActorCaller" | "ActorRefusalLog" | "ActorUnlink" | "AutoMutexAlloc" | "AutoMutexFree" | "AutoMutexLock" | "AutoMutexUnlock" | "DequePopFront" | "DequePopBack" | "BytesAppend" | "BytesClear" | "BytesConcat" | "BytesContains" | "BytesDecodeUtf8" | "BytesDecodeUtf8Lossy" | "BytesEndsWith" | "BytesGet" | "BytesIndex" | "BytesIsEmpty" | "BytesLen" | "BytesPop" | "BytesPush" | "BytesSet" | "BytesSlice" | "BytesSliceFrom" | "BytesStartsWith" | "BytesNew" | "CancelTokenIsRequested" | "CancelTokenRelease" | "CancelTokenRetain" | "ContextActorId" | "ContextSupervisor" | "ContextTraceSpan" | "ActorRequestRelease" | "ActorCallFree" | "ActorRequestTake" | "DurationAbs" | "DurationHours" | "DurationIsZero" | "DurationMicros" | "DurationMillis" | "DurationMins" | "DurationNanos" | "DurationSecs" | "DynBoxAlloc" | "DynBoxFree" | "HashMapContainsKeyLayout" | "HashMapClearLayout" | "HashMapCloneLayout" | "HashMapEntriesLayout" | "HashMapFreeLayout" | "HashMapGetLayout" | "HashMapInsertLayout" | "HashMapKeysLayout" | "HashMapLenLayout" | "HashMapNew" | "HashMapNewWithLayout" | "HashMapRemoveLayout" | "HashMapValuesLayout" | "HashSetContainsLayout" | "HashSetClearLayout" | "HashSetCloneLayout" | "HashSetFreeLayout" | "HashSetInsertLayout" | "HashSetIsEmptyLayout" | "HashSetLenLayout" | "HashSetNew" | "HashSetNewWithLayout" | "HashSetRemoveLayout" | "HashSetToVecLayout" | "InstantDurationSince" | "InstantElapsed" | "InstantNow" | "TimestampNow" | {
|
|
663
663
|
MathIntrinsic: MathIntrinsic;
|
|
664
664
|
} | {
|
|
665
665
|
IntMethod: [IntBitOp, IntMethodWidth];
|
|
@@ -791,6 +791,7 @@ export type SupervisorShape = {
|
|
|
791
791
|
strategy: RestartStrategy;
|
|
792
792
|
max_restarts: number;
|
|
793
793
|
window_secs: number;
|
|
794
|
+
backoff?: boolean;
|
|
794
795
|
children: Array<SupervisorChild>;
|
|
795
796
|
startup_order?: Array<number>;
|
|
796
797
|
};
|