fix order of execution

This commit is contained in:
Avraham Sakal
2023-05-17 16:28:32 -04:00
parent 3e769c0fa5
commit 636ba279c8
8 changed files with 274 additions and 119 deletions
+1 -1
View File
@@ -43,4 +43,4 @@ const machine =
),
);
const actor = Interpreter<C>(machine, {context:{}});
const actor = Interpreter<C>(machine, {context:{}}).start();
+45 -22
View File
@@ -1,34 +1,44 @@
import { Machine, State, On, SideEffect, Goto, Spawn, Unspawn, Interpreter, Interpreter_T, send, Event_T, Context, SideEffectFunction_T } from '../index';
import { Machine, State, On, SideEffect, Goto, Interpreter, Interpreter_T, send, Event_T, Context, SideEffectFunction_T, Peer, PeerCreationFunction_T, ContextMutationFunction_T } from '../index';
const wait = (ms:number)=>new Promise((resolve)=>{ setTimeout(()=>{ resolve(1); }, ms); });
const makeRequest : SideEffectFunction_T<Cc> = (ctx,e,self)=>{ send(ctx.serverActor, ['received-request',self]); };
const sendResponse : SideEffectFunction_T<Cs> = (ctx,e,self)=>{ send(ctx.clientActor, ['received-response',self]); };
const startTimer : SideEffectFunction_T<Cs> = async (ctx,e,self)=>{ await wait(1500); send(self, ['timer-finished',null]); }
const log : SideEffectFunction_T<Cc|Cs> = (ctx, e, self)=>{ console.log(self.state, ctx); };
const makeRequest : SideEffectFunction_T<Cc> = (ctx,e,self)=>{ send(self.peers.server, ['received-request',self]); };
const sendResponse : SideEffectFunction_T<Cs> = (ctx,e,self)=>{ send(ctx.client, ['received-response',self]); };
const startTimer : SideEffectFunction_T<Cs> = async (ctx,e,self)=>{ await wait(1500); console.log(' timer actually finished'); send(self, ['timer-finished',null]); }
const log = (namespace:string)=>(ctx, e, self)=>{ console.log(namespace, self.state, e[0]); };
const logClientStats : SideEffectFunction_T<Cc> = (ctx,e,self)=>{ console.log('client', ctx.requestsMade, ctx.responsesReceived); }
const logServerStats : SideEffectFunction_T<Cs> = (ctx,e,self)=>{ console.log('server', ctx.requestsReceived, ctx.responsesSent); }
const logEventQueue = (namespace:string)=>(ctx,e,self)=>{ console.log(namespace+'.eventQueue', [e[0]], self.eventQueue.map(([eventName])=>eventName)); }
const saveClient : ContextMutationFunction_T<Cs> = (ctx, e, self)=>({...ctx, client:e[1]});
const createServer : PeerCreationFunction_T<Cc,Cs> = (ctx, e, self)=>Interpreter(server,{requestsReceived:0, responsesSent:0}).start();
type Cc = {
requestsMade: number;
responsesReceived: number;
serverActor: Interpreter_T<Cs>;
};
type Cs = {
clientActor: Interpreter_T<Cc>
client: Interpreter_T<Cc>;
requestsReceived:number;
responsesSent:number;
};
const client =
Machine<Cc>(
State('initializing',
On('entry',
Peer('server', createServer),
//SideEffect(log('client')),
Goto('idle'),
)
),
State<Cc>('idle',
On<Cc>('entry',
SideEffect(log),
),
On('server-created',
SideEffect((_ctx,[_eventName,serverActor],self)=>{ self.context.serverActor=serverActor; }),
//SideEffect(log('client')),
Goto('making-request')
)
),
State<Cc>('making-request',
On<Cc>('entry',
SideEffect(log),
//SideEffect(log('client')),
SideEffect(makeRequest),
Context<Cc>((ctx)=>({...ctx, requestsMade: ctx.requestsMade+1})),
Goto('awaiting-response')
@@ -36,11 +46,11 @@ const client =
),
State<Cc>('awaiting-response',
On<Cc>('entry',
SideEffect(log),
//SideEffect(log('client')),
),
On<Cc>('received-response',
SideEffect(log),
Context<Cc>((ctx)=>({...ctx, responsesReceived: ctx.responsesReceived+1})),
//SideEffect(log('client')),
Goto('making-request')
),
),
@@ -50,25 +60,38 @@ const server =
Machine<Cs>(
State<Cs>('awaiting-request',
On<Cs>('entry',
SideEffect(log),
//SideEffect(log('server')),
Context<Cs>((ctx)=>({...ctx, requestsReceived: ctx.requestsReceived+1})),
),
On('received-request',
SideEffect((_ctx,[_eventName,clientActor],self)=>{ self.context.clientActor=clientActor; }),
//SideEffect(log('server')),
Context<Cs>(saveClient),
Goto('sending-response')
),
),
State<Cs>('sending-response',
On<Cs>('entry',
SideEffect(log),
//SideEffect(log('server')),
SideEffect(startTimer)
),
On('timer-finished',
//SideEffect(log('server')),
SideEffect(logServerStats),
SideEffect(sendResponse),
Goto('awaiting-request')
)
Context<Cs>((ctx)=>({...ctx, responsesSent: ctx.responsesSent+1})),
Goto('awaiting-request') // for some reason, at this point there's a "received-request" waiting in the eventQueue, which gets processed before the "exit" then "entry" that get appended to the queue due to this Goto, which makes the Interpreter come right back to this State
/*
Server gets timer-finished, which sends response to client.
But client, at the time, is not transitioning, so it immediately begins
processing that event. The problem is that one of the sideeffects involved
in processing that event is to send another request to the server,
which hasn't yet even queued `exit`-then-`entry` events for its next state!
So we have to ensure they get queued first, before processing the client.
*/
),
),
);
const clientActor = Interpreter(client, {context:{requestsMade:0, responsesReceived:0}});
const serverActor = Interpreter(server, {context:{}});
send(clientActor, ['server-created', serverActor]);
const clientActor = Interpreter(client, {requestsMade:0, responsesReceived:0}).start();