Skip to content

Commit

Permalink
stop the server once there are no more typeholes
Browse files Browse the repository at this point in the history
  • Loading branch information
rikukissa committed May 13, 2021
1 parent f40babb commit 32f05fe
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 73 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,14 @@ At this stage, there are no configuration options available.

## [Unreleased]

## [1.4.1] - 2021-05-09

### Fixed

- Unserializable diagnostic now shown only once per typehole. Previously the tooltip could have the same warning multiple times.

- Server is now stopped once all typeholes are removed. Restarting the server now also works

### Added

## [1.4.0] - 2021-05-09
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"publisher": "rikurouvila",
"description": "🧪 Take samples of runtime values and turn them into type definitions automatically",
"repository": "https://github.com/rikukissa/typehole",
"version": "1.4.0",
"version": "1.4.1",
"private": true,
"icon": "images/logo.png",
"galleryBanner": {
Expand All @@ -15,7 +15,6 @@
"vscode": "^1.55.0"
},
"categories": [
"Debuggers",
"Other"
],
"activationEvents": [
Expand Down
19 changes: 3 additions & 16 deletions packages/extension/src/commands/addATypehole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
getNodeEndPosition,
getParentOnRootLevel,
} from "../parse/module";
import { isServerRunning, startListenerServer } from "../listener";

import { getAvailableId } from "../state";
import {
insertTypeholeImport,
Expand Down Expand Up @@ -156,18 +156,6 @@ export async function addATypehole() {
return;
}

if (!isServerRunning()) {
try {
vscode.window.showInformationMessage("Typehole: Starting server...");
await startListenerServer();
vscode.window.showInformationMessage("Typehole: Server ready");
} catch (error) {
vscode.window.showErrorMessage(
"Typehole failed to start: " + error.message
);
}
}

const fullFile = document.getText();
const ast = getAST(fullFile);
const id = getAvailableId();
Expand All @@ -183,9 +171,8 @@ export async function addATypehole() {

const newlyCreatedTypeHole = last(findTypeholes(updatedAST));

const variableDeclaration = getWrappingVariableDeclaration(
newlyCreatedTypeHole
);
const variableDeclaration =
getWrappingVariableDeclaration(newlyCreatedTypeHole);

const typeName = getPlaceholderTypeName(updatedAST);
await editor.edit((editBuilder) => {
Expand Down
60 changes: 43 additions & 17 deletions packages/extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,21 @@ import {
getDescendantAtRange,
lineCharacterPositionInText,
} from "./parse/utils";
import { startListenerServer, stopListenerServer } from "./listener";
import {
isServerRunning,
startListenerServer,
stopListenerServer,
} from "./listener";
import { getEditorRange, getProjectURI } from "./editor/utils";
import { TypeHoler } from "./code-action";
import { clearWarnings, getState, onFileChanged, onFileDeleted } from "./state";
import {
clearWarnings,
events,
getState,
onFileChanged,
onFileDeleted,
State,
} from "./state";

import { readFile } from "fs";
import { log } from "./logger";
Expand Down Expand Up @@ -127,6 +138,36 @@ export async function activate(context: vscode.ExtensionContext) {
"**/*.{tsx,ts}"
);

/*
* Start and stop HTTP listener based on the amount of holes
*/

let previousState = getState();
events.on("change", async (newState: State) => {
const allHolesRemoved =
previousState.holes.length > 0 && newState.holes.length === 0;

previousState = newState;

if (allHolesRemoved) {
vscode.window.showInformationMessage("Typehole: Stopping the server");
await stopListenerServer();
vscode.window.showInformationMessage("Typehole: Server stopped");
}

if (newState.holes.length > 0 && !isServerRunning()) {
try {
vscode.window.showInformationMessage("Typehole: Starting server...");
await startListenerServer();
vscode.window.showInformationMessage("Typehole: Server ready");
} catch (error) {
vscode.window.showErrorMessage(
"Typehole failed to start the HTTP listener: " + error.message
);
}
}
});

/*
* Initialize state
*/
Expand All @@ -141,21 +182,6 @@ export async function activate(context: vscode.ExtensionContext) {
const holes = getState().holes;
log("Found", holes.length.toString(), "holes in the workspace");

if (holes.length > 0) {
try {
log("Starting the server");
await startListenerServer();
vscode.window.showInformationMessage(
"Typehole server ready to receive samples."
);
} catch (error) {
vscode.window.showErrorMessage(
"Typehole failed to start its server. Make sure you are not running typehole server in multiple VSCode windows and port 17341 is available for listening."
);
error("Failed to start server", error.message);
}
}

/*
* Setup file watchers to enable holes in multile files
*/
Expand Down
82 changes: 46 additions & 36 deletions packages/extension/src/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,56 +14,60 @@ import {
} from "./transforms/insertTypes";
import { samplesToType } from "./transforms/samplesToType";

const fastify = f({ logger: true });
fastify.register(require("fastify-cors"));

let running = false;
export function isServerRunning() {
return running;
}
let server = createServer();

fastify.post("/type", async (request, reply) => {
vscode.window.showWarningMessage(
"Typehole: You seem to be running an old version of the runtime. Remove 'typehole' package from node_modules and add a new typehole to download the latest version or install it manually."
);
return reply.code(200).send();
});

fastify.post("/samples", async (request, reply) => {
const body = request.body as any;
log(
body.id,
"-",
"New sample",
JSON.stringify(request.body).substr(0, 30),
"received"
);
function createServer() {
const fastify = f({ logger: true });
fastify.register(require("fastify-cors"));

const samples = addSample(clientIdToStateId(body.id), body.sample);
const typeString = samplesToType(samples);
fastify.post("/type", async (request, reply) => {
vscode.window.showWarningMessage(
"Typehole: You seem to be running an old version of the runtime. Remove 'typehole' package from node_modules and add a new typehole to download the latest version or install it manually."
);
return reply.code(200).send();
});

try {
await onTypeExtracted(body.id, typeString);
} catch (err) {
error(err.message);
}
fastify.post("/samples", async (request, reply) => {
const body = request.body as any;
log(
body.id,
"-",
"New sample",
JSON.stringify(request.body).substr(0, 30),
"received"
);

const samples = addSample(clientIdToStateId(body.id), body.sample);
const typeString = samplesToType(samples);

return reply.code(200).send();
});
try {
await onTypeExtracted(body.id, typeString);
} catch (err) {
error(err.message);
}

fastify.post("/unserializable", async (request, reply) => {
const body = request.body as any;
error("Value in typehole", body.id, "is unserializable");
onUnserializable(body.id);
return reply.code(200).send();
});
return reply.code(200).send();
});

fastify.post("/unserializable", async (request, reply) => {
const body = request.body as any;
error("Value in typehole", body.id, "is unserializable");
onUnserializable(body.id);
return reply.code(200).send();
});
return fastify;
}

export async function startListenerServer() {
log("Requesting HTTP server start");
running = true;

try {
await fastify.listen(17341);
await server.listen(17341);
log("HTTP server started");
} catch (err) {
error("Starting HTTP server failed");
Expand All @@ -74,8 +78,14 @@ export async function startListenerServer() {
}

export async function stopListenerServer() {
log("Stopping the HTTP server");
try {
await fastify.close();
await server.close();
// Server is recreated as Fastify doesn't support closing and restarting a server
// https://github.com/fastify/fastify/issues/2411
server = createServer();
running = false;
log("HTTP server server stopped");
} catch (error) {
running = false;
}
Expand Down

0 comments on commit 32f05fe

Please sign in to comment.