Attach connection handler earlier
Summary: This change attaches our event handlers as soon as the ws is created. As a consequence, we need to wait until the server has created any necessary instances required to process incoming requests. To achieve this, I created a type called `Lazy`. This type wraps around a value and a promise to that value. Callers can check if the value is set. If not, callers can wait for it. Ultimately, the value can be set outside of the promise itself. Reviewed By: passy Differential Revision: D37284939 fbshipit-source-id: 17dec548d7155a3d65440c9584cec07cbb826c37
This commit is contained in:
committed by
Facebook GitHub Bot
parent
40e65901bd
commit
8c67b049ab
@@ -16,7 +16,6 @@ import {
|
|||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
import {createFlipperServer, FlipperServerState} from 'flipper-frontend-core';
|
import {createFlipperServer, FlipperServerState} from 'flipper-frontend-core';
|
||||||
import {
|
import {
|
||||||
attachSocketServer,
|
|
||||||
FlipperServerImpl,
|
FlipperServerImpl,
|
||||||
getEnvironmentInfo,
|
getEnvironmentInfo,
|
||||||
getGatekeepers,
|
getGatekeepers,
|
||||||
@@ -93,13 +92,13 @@ async function getFlipperServer(
|
|||||||
if (!(await checkSocketInUse(socketPath))) {
|
if (!(await checkSocketInUse(socketPath))) {
|
||||||
console.info('flipper-server: not running/listening, start');
|
console.info('flipper-server: not running/listening, start');
|
||||||
|
|
||||||
const {socket} = await startServer({
|
const {readyForIncomingConnections} = await startServer({
|
||||||
port: 52342,
|
port: 52342,
|
||||||
staticDir: staticPath,
|
staticDir: staticPath,
|
||||||
entry: 'index.web.dev.html',
|
entry: 'index.web.dev.html',
|
||||||
});
|
});
|
||||||
|
|
||||||
const flipperServer = await startFlipperServer(
|
const server = await startFlipperServer(
|
||||||
appPath,
|
appPath,
|
||||||
staticPath,
|
staticPath,
|
||||||
'',
|
'',
|
||||||
@@ -107,10 +106,10 @@ async function getFlipperServer(
|
|||||||
keytar,
|
keytar,
|
||||||
);
|
);
|
||||||
|
|
||||||
const companionEnv = await initCompanionEnv(flipperServer);
|
const companionEnv = await initCompanionEnv(server);
|
||||||
await flipperServer.connect();
|
await server.connect();
|
||||||
|
|
||||||
attachSocketServer(flipperServer, socket, companionEnv);
|
await readyForIncomingConnections(server, companionEnv);
|
||||||
} else {
|
} else {
|
||||||
console.info('flipper-server: already running');
|
console.info('flipper-server: already running');
|
||||||
const loggerOutputFile = 'flipper-server-log.out';
|
const loggerOutputFile = 'flipper-server-log.out';
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ const safe = (f: () => void) => {
|
|||||||
* @param socket A ws socket on which to listen for events.
|
* @param socket A ws socket on which to listen for events.
|
||||||
*/
|
*/
|
||||||
export function attachSocketServer(
|
export function attachSocketServer(
|
||||||
flipperServer: FlipperServerImpl,
|
|
||||||
socket: WebSocketServer,
|
socket: WebSocketServer,
|
||||||
|
server: FlipperServerImpl,
|
||||||
companionEnv: FlipperServerCompanionEnv,
|
companionEnv: FlipperServerCompanionEnv,
|
||||||
) {
|
) {
|
||||||
socket.on('connection', (client, req) => {
|
socket.on('connection', (client, req) => {
|
||||||
@@ -53,7 +53,6 @@ export function attachSocketServer(
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
console.log('Client connected', clientAddress);
|
console.log('Client connected', clientAddress);
|
||||||
|
|
||||||
let connected = true;
|
let connected = true;
|
||||||
|
|
||||||
let flipperServerCompanion: FlipperServerCompanion | undefined;
|
let flipperServerCompanion: FlipperServerCompanion | undefined;
|
||||||
@@ -62,7 +61,7 @@ export function attachSocketServer(
|
|||||||
|
|
||||||
if (params.get('server_companion')) {
|
if (params.get('server_companion')) {
|
||||||
flipperServerCompanion = new FlipperServerCompanion(
|
flipperServerCompanion = new FlipperServerCompanion(
|
||||||
flipperServer,
|
server,
|
||||||
getLogger(),
|
getLogger(),
|
||||||
companionEnv.pluginInitializer.initialPlugins,
|
companionEnv.pluginInitializer.initialPlugins,
|
||||||
);
|
);
|
||||||
@@ -112,7 +111,7 @@ export function attachSocketServer(
|
|||||||
client.send(JSON.stringify(message));
|
client.send(JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
flipperServer.onAny(onServerEvent);
|
server.onAny(onServerEvent);
|
||||||
|
|
||||||
async function onServerCompanionEvent(event: string, payload: any) {
|
async function onServerCompanionEvent(event: string, payload: any) {
|
||||||
const message = {
|
const message = {
|
||||||
@@ -167,7 +166,7 @@ export function attachSocketServer(
|
|||||||
|
|
||||||
const execRes = flipperServerCompanion?.canHandleCommand(command)
|
const execRes = flipperServerCompanion?.canHandleCommand(command)
|
||||||
? flipperServerCompanion.exec(command, ...args)
|
? flipperServerCompanion.exec(command, ...args)
|
||||||
: flipperServer.exec(command, ...args);
|
: server.exec(command, ...args);
|
||||||
|
|
||||||
execRes
|
execRes
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
@@ -229,7 +228,7 @@ export function attachSocketServer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
connected = false;
|
connected = false;
|
||||||
flipperServer.offAny(onServerEvent);
|
server.offAny(onServerEvent);
|
||||||
flipperServerCompanion?.destroyAll();
|
flipperServerCompanion?.destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import {makeSocketPath, checkSocketInUse} from './utilities';
|
|||||||
|
|
||||||
import proxy from 'http-proxy';
|
import proxy from 'http-proxy';
|
||||||
import exitHook from 'exit-hook';
|
import exitHook from 'exit-hook';
|
||||||
|
import {attachSocketServer} from './attachSocketServer';
|
||||||
|
import {FlipperServerImpl} from '../FlipperServerImpl';
|
||||||
|
import {FlipperServerCompanionEnv} from 'flipper-server-companion';
|
||||||
|
|
||||||
type Config = {
|
type Config = {
|
||||||
port: number;
|
port: number;
|
||||||
@@ -27,6 +30,11 @@ type Config = {
|
|||||||
entry: string;
|
entry: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ReadyForConnections = (
|
||||||
|
server: FlipperServerImpl,
|
||||||
|
companionEnv: FlipperServerCompanionEnv,
|
||||||
|
) => Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orchestrates the creation of the HTTP server, proxy, and web socket.
|
* Orchestrates the creation of the HTTP server, proxy, and web socket.
|
||||||
* @param config Server configuration.
|
* @param config Server configuration.
|
||||||
@@ -36,14 +44,9 @@ export async function startServer(config: Config): Promise<{
|
|||||||
app: Express;
|
app: Express;
|
||||||
server: http.Server;
|
server: http.Server;
|
||||||
socket: WebSocketServer;
|
socket: WebSocketServer;
|
||||||
|
readyForIncomingConnections: ReadyForConnections;
|
||||||
}> {
|
}> {
|
||||||
const {app, server} = await startHTTPServer(config);
|
return await startHTTPServer(config);
|
||||||
const socket = addWebsocket(server, config);
|
|
||||||
return {
|
|
||||||
app,
|
|
||||||
server,
|
|
||||||
socket,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,9 +55,12 @@ export async function startServer(config: Config): Promise<{
|
|||||||
* @param config Server configuration.
|
* @param config Server configuration.
|
||||||
* @returns A promise to both app and HTTP server.
|
* @returns A promise to both app and HTTP server.
|
||||||
*/
|
*/
|
||||||
async function startHTTPServer(
|
async function startHTTPServer(config: Config): Promise<{
|
||||||
config: Config,
|
app: Express;
|
||||||
): Promise<{app: Express; server: http.Server}> {
|
server: http.Server;
|
||||||
|
socket: WebSocketServer;
|
||||||
|
readyForIncomingConnections: ReadyForConnections;
|
||||||
|
}> {
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
app.use((_req, res, next) => {
|
app.use((_req, res, next) => {
|
||||||
@@ -89,8 +95,14 @@ async function startHTTPServer(
|
|||||||
async function startProxyServer(
|
async function startProxyServer(
|
||||||
config: Config,
|
config: Config,
|
||||||
app: Express,
|
app: Express,
|
||||||
): Promise<{app: Express; server: http.Server}> {
|
): Promise<{
|
||||||
|
app: Express;
|
||||||
|
server: http.Server;
|
||||||
|
socket: WebSocketServer;
|
||||||
|
readyForIncomingConnections: ReadyForConnections;
|
||||||
|
}> {
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
const socket = addWebsocket(server, config);
|
||||||
|
|
||||||
// For now, we only support domain socket access on POSIX-like systems.
|
// For now, we only support domain socket access on POSIX-like systems.
|
||||||
// On Windows, a proxy is not created and the server starts
|
// On Windows, a proxy is not created and the server starts
|
||||||
@@ -98,7 +110,12 @@ async function startProxyServer(
|
|||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
console.log(`Starting server on http://localhost:${config.port}`);
|
console.log(`Starting server on http://localhost:${config.port}`);
|
||||||
server.listen(config.port, undefined, () => resolve({app, server}));
|
const readyForIncomingConnections = (): Promise<void> => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
server.listen(config.port, undefined, () => resolve());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
resolve({app, server, socket, readyForIncomingConnections});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +156,18 @@ async function startProxyServer(
|
|||||||
res.end('Failed to proxy request: ' + err);
|
res.end('Failed to proxy request: ' + err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const readyForIncomingConnections = (
|
||||||
|
serverImpl: FlipperServerImpl,
|
||||||
|
companionEnv: FlipperServerCompanionEnv,
|
||||||
|
): Promise<void> => {
|
||||||
|
attachSocketServer(socket, serverImpl, companionEnv);
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
proxyServer.listen(config.port);
|
proxyServer.listen(config.port);
|
||||||
server.listen(socketPath, undefined, () => resolve({app, server}));
|
server.listen(socketPath, undefined, () => resolve());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
resolve({app, server, socket, readyForIncomingConnections});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,7 @@ import fs from 'fs-extra';
|
|||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import open from 'open';
|
import open from 'open';
|
||||||
import {initCompanionEnv} from 'flipper-server-companion';
|
import {initCompanionEnv} from 'flipper-server-companion';
|
||||||
import {
|
import {startFlipperServer, startServer} from 'flipper-server-core';
|
||||||
attachSocketServer,
|
|
||||||
startFlipperServer,
|
|
||||||
startServer,
|
|
||||||
} from 'flipper-server-core';
|
|
||||||
import {isTest} from 'flipper-common';
|
import {isTest} from 'flipper-common';
|
||||||
|
|
||||||
const argv = yargs
|
const argv = yargs
|
||||||
@@ -97,7 +93,7 @@ async function start() {
|
|||||||
console.error('Failed to load keytar:', e);
|
console.error('Failed to load keytar:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {app, server, socket} = await startServer({
|
const {app, server, socket, readyForIncomingConnections} = await startServer({
|
||||||
port: argv.port,
|
port: argv.port,
|
||||||
staticDir,
|
staticDir,
|
||||||
entry: 'index.web.dev.html',
|
entry: 'index.web.dev.html',
|
||||||
@@ -123,7 +119,7 @@ async function start() {
|
|||||||
if (argv.bundler) {
|
if (argv.bundler) {
|
||||||
await attachDevServer(app, server, socket, rootDir);
|
await attachDevServer(app, server, socket, rootDir);
|
||||||
}
|
}
|
||||||
attachSocketServer(flipperServer, socket, companionEnv);
|
await readyForIncomingConnections(flipperServer, companionEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
Reference in New Issue
Block a user