import { Actor, Assertion, Handle, Ref, Turn, attenuate, rfilter, PCompound, CRec, Lit, } from './actor.js'; import { Dictionary, Record } from 'preserves'; import { Dataspace, Observe } from './dataspace.js'; const BoxState = Record.makeConstructor<{value: number}, Ref>()( Symbol.for('BoxState'), ['value']); const SetBox = Record.makeConstructor<{newValue: number}, Ref>()( Symbol.for('SetBox'), ['newValue']); let startTime = Date.now(); let prevValue = 0; const LIMIT = 500000; function spawnBox(t: Turn, ds: Ref) { t.spawn(t => { console.log('Spawning Box'); let valueHandle: Handle | undefined; function setValue(t: Turn, value: number) { valueHandle = t.replace(ds, valueHandle, BoxState(value)); } setValue(t, 0); t.assert(ds, Observe(SetBox.constructorInfo.label, t.ref({ message(t: Turn, [newValue]: [number]): void { // console.log(`Box: got ${newValue}`); if (newValue % 25000 === 0) { const endTime = Date.now(); const delta = (endTime - startTime) / 1000.0; const count = newValue - prevValue; prevValue = newValue; startTime = endTime; console.log(`Box: got ${newValue} (${count / delta} Hz)`); } if (newValue === LIMIT - 20000) t.quit(); setValue(t, newValue); } }))); }); } function spawnClient(t: Turn, ds: Ref) { t.spawn(t => { console.log('Spawning Client'); let count = 0; t.assert(ds, Observe(BoxState.constructorInfo.label, t.ref({ assert(t: Turn, [currentValue]: [number]): void { // console.log(`Client: got ${currentValue}`); if (currentValue === LIMIT) { console.log(`Client: quitting at limit`); t.quit(); } else { t.message(ds, SetBox(currentValue + 1)); } } }))); t.assert(ds, Observe(BoxState.constructorInfo.label, t.ref({ assert(_t: Turn, _assertion: Assertion): void { count++; }, retract(t: Turn, _handle: Handle) { if (--count === 0) { console.log('Client: detected box termination'); t.quit(); } }, }))); }); } Turn.for(new Actor(), async (t: Turn) => { const ds = t.ref(new Dataspace()); spawnBox(t, attenuate( ds, rfilter(PCompound(CRec(BoxState.constructorInfo.label, BoxState.constructorInfo.arity), new Dictionary()), PCompound(CRec(Observe.constructorInfo.label, Observe.constructorInfo.arity), new Dictionary([[0, Lit(SetBox.constructorInfo.label)]]))))); spawnClient(t, attenuate( ds, rfilter(PCompound(CRec(SetBox.constructorInfo.label, SetBox.constructorInfo.arity), new Dictionary()), PCompound(CRec(Observe.constructorInfo.label, Observe.constructorInfo.arity), new Dictionary([[0, Lit(BoxState.constructorInfo.label)]]))))); });