Skip to content

Commit

Permalink
wait until simulation server is fully stopped
Browse files Browse the repository at this point in the history
  • Loading branch information
wKich committed Oct 5, 2021
1 parent 04547a6 commit 00af962
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changes/wait-server-stops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@simulacrum/server": patch
---

Fix #127. Wait until simulation server is fully stopped in `destroySimulation` request
6 changes: 3 additions & 3 deletions packages/server/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function map<A>(slice: Slice<Record<string, A>>, effect: Effect<A>): Oper
return function* (scope) {
let effects = new Map<string, Task>();

function synchronize(record: Record<string, A>) {
function* synchronize(record: Record<string, A>) {
let keep = new Set<string>();

// the checks for non-null `record` and `value`
Expand All @@ -31,12 +31,12 @@ export function map<A>(slice: Slice<Record<string, A>>, effect: Effect<A>): Oper
for (let [key, effect] of effects.entries()) {
if (!keep.has(key)) {
effects.delete(key);
effect.halt();
yield effect.halt();
}
}
}

synchronize(slice.get());
yield synchronize(slice.get());

yield slice.forEach(synchronize);
};
Expand Down
6 changes: 4 additions & 2 deletions packages/server/src/http.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ServerOptions as SSLOptions } from 'https';
import type { AddressInfo } from 'net';
import type { Service } from './interfaces';
import { Operation, once, Resource, spawn, label } from 'effection';
import { Operation, once, Resource, spawn, label, createFuture } from 'effection';
import { Request, Response, Application, RequestHandler } from 'express';
import { createServer as createHttpsServer } from 'https';
import { Server as HTTPServer, createServer as createHttpServer } from 'http';
Expand Down Expand Up @@ -63,7 +63,9 @@ export function createServer(app: Application, options: ServerOptions): Resource
try {
yield;
} finally {
server.close();
let { future, resolve, reject } = createFuture<void>();
server.close((err) => err ? reject(err) : resolve());
yield future;
}
});

Expand Down
20 changes: 20 additions & 0 deletions packages/server/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ export type SimulationState =
services: [];
store: StoreState;
error: Error
} |
{
id: string;
status: 'destroying';
simulator: string;
options: SimulationOptions;
scenarios: Record<string, ScenarioState>;
services: [];
store: StoreState;
error: Error;
} |
{
id: string;
status: 'halted';
simulator: string;
options: SimulationOptions;
scenarios: Record<string, ScenarioState>;
services: [];
store: StoreState;
error: Error;
}

export type ScenarioState =
Expand Down
6 changes: 4 additions & 2 deletions packages/server/src/schema/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ export const createSimulation: Resolver<CreateSimulationParameters, SimulationSt
}
};

export const destroySimulation: Resolver<{ id: string; }, boolean> = {
async resolve({ id }, { atom }) {
export const destroySimulation: Resolver<{ id: string }, boolean> = {
async resolve({ id }, { atom, scope }) {
let simulation = atom.slice("simulations", id);
if (simulation.get()) {
simulation.slice("status").set("destroying");
await scope.run(simulation.filter(({ status }) => status == "halted").expect());
simulation.remove();
return true;
} else {
Expand Down
13 changes: 11 additions & 2 deletions packages/server/src/simulation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { spawn, label } from 'effection';
import { Slice } from '@effection/atom';
import { assert } from 'assert-ts';
import { Effect, map } from './effect';
import express, { raw } from 'express';
Expand All @@ -7,8 +8,8 @@ import { createServer, Server } from './http';
import { createFaker } from './faker';
import { middlewareHandlerIsOperation, isRequestHandler } from './guards/guards';

export function simulation(simulators: Record<string, Simulator>): Effect<SimulationState> {
return slice => function*(scope) {
function createSimulation (slice: Slice<SimulationState>, simulators: Record<string, Simulator>) {
return spawn(function* (scope) {
let simulatorName = slice.get().simulator;
yield label({ name: 'simulation', simulator: simulatorName });
try {
Expand Down Expand Up @@ -127,6 +128,14 @@ export function simulation(simulators: Record<string, Simulator>): Effect<Simula
services: []
}));
}
});
}

export function simulation(simulators: Record<string, Simulator>): Effect<SimulationState> {
return function* (slice) {
let simulationTask = yield createSimulation(slice, simulators);
yield slice.filter(({ status }) => status == "destroying").expect();
yield simulationTask.halt();
slice.slice("status").set("halted");
};
}

0 comments on commit 00af962

Please sign in to comment.