Don't hog the runtime permanently with spinning actors

This commit is contained in:
Tony Garnock-Jones 2021-03-02 13:58:03 +01:00
parent b6473eee6d
commit 58791867f3
3 changed files with 19 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import { Dictionary, IdentitySet, Record, Tuple, Value, is, preserves } from 'preserves';
import { queueTask } from './task.js';
//---------------------------------------------------------------------------
@ -126,13 +127,13 @@ export class Actor {
console.error(`Actor ${this.id} crashed:`, this.exitReason.err);
}
// this.exitHooks.forEach(hook => hook(t));
queueMicrotask(() =>
queueTask(() =>
t.freshen(t =>
this.outbound.forEach((peer, h) => t._retract(peer, h))));
}
execute(proc: () => void): void {
queueMicrotask(() => {
queueTask(() => {
if (this.exitReason !== null) return;
try {
proc();

View File

@ -15,6 +15,7 @@ import {
WireRef,
TurnMessage,
} from './protocol.js';
import { queueTask } from './task.js';
export class SyncPeerEntity implements Entity {
readonly relay: Relay;
@ -205,7 +206,7 @@ export class Relay {
send(remoteOid: Oid, m: EntityMessage): void {
if (this.pendingTurn.length === 0) {
queueMicrotask(() => {
queueTask(() => {
if (this.debug) console.log('OUT', this.pendingTurn.asPreservesText());
this.w(underlying(encode<WireRef>(this.pendingTurn, {
canonical: true,

14
src/task.ts Normal file
View File

@ -0,0 +1,14 @@
const LIMIT = 25000;
let taskCounter = 0;
export function queueTask(f: () => void) {
taskCounter++;
if (taskCounter === LIMIT) {
setTimeout(() => taskCounter = 0, 0);
}
if (taskCounter >= LIMIT) {
setTimeout(f, 0);
} else {
queueMicrotask(f);
}
}