Tighten and simplify

This commit is contained in:
Tony Garnock-Jones 2021-02-22 22:30:36 +01:00
parent 6a5cac5328
commit 2f3a249ab5
2 changed files with 19 additions and 34 deletions

View File

@ -45,21 +45,19 @@ export class Actor {
}
terminateWith(t: Turn, reason: Exclude<ExitReason, null>) {
if (this.alive) {
this.exitReason = reason;
this.outbound.forEach((peer, h) => t._retract(peer, h));
}
if (!this.alive) return;
this.exitReason = reason;
this.outbound.forEach((peer, h) => t._retract(peer, h));
}
execute(proc: () => void): void {
queueMicrotask(() => {
if (this.alive) {
try {
proc();
} catch (err) {
console.error(Actor, err);
Turn.for(this, t => this.terminateWith(t, { ok: false, err }));
}
if (!this.alive) return;
try {
proc();
} catch (err) {
console.error(Actor, err);
Turn.for(this, t => this.terminateWith(t, { ok: false, err }));
}
});
}
@ -86,9 +84,7 @@ export class Turn {
}
_ensureActor(what: string): Actor {
if (this.actor === null) {
throw new Error(`Cannot ${what} from non-Actor context`);
}
if (this.actor === null) throw new Error(`Cannot ${what} from non-Actor context`);
return this.actor;
}
@ -101,10 +97,9 @@ export class Turn {
this._ensureActor("spawn with initialAssertions");
}
this.localActions.push(() => {
const transferred = this.actor === null
const child = new Actor(this.actor === null
? void 0
: extractFromMap(this.actor.outbound, initialAssertions);
const child = new Actor(transferred);
: extractFromMap(this.actor.outbound, initialAssertions));
child.execute(() => Turn.for(child, bootProc));
});
}
@ -155,8 +150,7 @@ export class Turn {
complete(): void {
if (this.completed) throw new Error("Reuse of completed Turn!");
this.completed = true;
this.queues.forEach((queue, actor) =>
actor.execute(() => queue.forEach(f => Turn.for(actor, f))));
this.queues.forEach((q, a) => a.execute(() => q.forEach(f => Turn.for(a, f))));
if (this.localActions.length > 0) {
queueMicrotask(() => this.localActions.forEach(f => Turn.for(this.actor, f)));
}
@ -167,11 +161,8 @@ function extractFromMap<K, V>(map: Map<K, V>, keys?: IdentitySet<K>): Map<K, V>
const result: Map<K, V> = new Map();
if (keys !== void 0) {
keys.forEach(key => {
const value = map.get(key);
if (value !== void 0) {
map.delete(key);
result.set(key, value);
}
if (map.has(key)) result.set(key, map.get(key)!);
map.delete(key);
});
}
return result;

14
main.ts
View File

@ -19,10 +19,6 @@ function makeDataspace(): Entity {
const assertions = new Bag<Ref<Entity>>();
const subscriptions: Dictionary<Map<Ref<Entity>, Dictionary<Handle>>> = new Dictionary();
function forEachSubscription(assertion: Record<Ref<Entity>>, f: (seen: Dictionary<Handle>, peer: Ref<Entity>) => void): void {
subscriptions.get(assertion.label)?.forEach(f);
}
return {
[assert](turn: Turn, rec: Assertion, handle: Handle): void {
if (!Record.isRecord<Ref<Entity>>(rec)) return;
@ -38,7 +34,7 @@ function makeDataspace(): Entity {
is((prev as Record<Ref<Entity>>).label, label)
&& seen.set(prev, turn.assert(observer, prev)));
}
forEachSubscription(rec, (seen, peer) =>
subscriptions.get(rec.label)?.forEach((seen, peer) =>
seen.has(rec) || seen.set(rec, turn.assert(peer, rec)));
},
@ -47,7 +43,7 @@ function makeDataspace(): Entity {
if (rec === void 0) return;
handleMap.delete(upstreamHandle);
if (assertions.change(rec, -1) !== ChangeDescription.PRESENT_TO_ABSENT) return;
forEachSubscription(rec, (seen, _peer) => {
subscriptions.get(rec.label)?.forEach((seen, _peer) => {
const downstreamHandle = seen.get(rec);
if (downstreamHandle !== void 0) {
turn.retract(downstreamHandle);
@ -63,7 +59,7 @@ function makeDataspace(): Entity {
[message](turn: Turn, rec: Assertion): void {
if (!Record.isRecord<Ref<Entity>>(rec)) return;
forEachSubscription(rec, (_seen, peer) => turn.message(peer, rec));
subscriptions.get(rec.label)?.forEach((_seen, peer) => turn.message(peer, rec));
}
};
}
@ -79,10 +75,8 @@ Turn.for(null, async (t: Turn) => {
// Box
t.spawn(t => {
console.log('Spawning Box');
let value: number;
let valueHandle: Handle | undefined;
function setValue(t: Turn, newValue: number) {
value = newValue;
function setValue(t: Turn, value: number) {
valueHandle = t.replace(ds, valueHandle, BoxState(value));
}
setValue(t, 0);