Decouple JS device from Store
Summary: Made a start with decoupling JS device. Incomplete as there are still Electron deps. Reviewed By: timur-valiev Differential Revision: D30309257 fbshipit-source-id: b8002170cbbe8d68e1795ce7c12ffce4c8eac853
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a9c6351cf0
commit
3736cbc480
@@ -10,14 +10,14 @@
|
||||
import React from 'react';
|
||||
import {Store} from '../reducers/index';
|
||||
import {Logger} from '../fb-interfaces/Logger';
|
||||
import {startFlipperServer} from '../server/FlipperServer';
|
||||
import {FlipperServer} from '../server/FlipperServer';
|
||||
import {selectClient, selectDevice} from '../reducers/connections';
|
||||
import Client from '../Client';
|
||||
import {notification} from 'antd';
|
||||
|
||||
export default async (store: Store, logger: Logger) => {
|
||||
const {enableAndroid, androidHome} = store.getState().settingsState;
|
||||
const server = startFlipperServer(
|
||||
const server = new FlipperServer(
|
||||
{
|
||||
enableAndroid,
|
||||
androidHome,
|
||||
@@ -101,7 +101,7 @@ export default async (store: Store, logger: Logger) => {
|
||||
}
|
||||
|
||||
server
|
||||
.waitForServerStarted()
|
||||
.start()
|
||||
.then(() => {
|
||||
console.log(
|
||||
'Flipper server started and accepting device / client connections',
|
||||
|
||||
@@ -48,18 +48,18 @@ export interface FlipperServerConfig {
|
||||
serverPorts: ServerPorts;
|
||||
}
|
||||
|
||||
export function startFlipperServer(
|
||||
config: FlipperServerConfig,
|
||||
store: Store,
|
||||
logger: Logger,
|
||||
): FlipperServer {
|
||||
const server = new FlipperServer(config, store, logger);
|
||||
server.start();
|
||||
return server;
|
||||
}
|
||||
|
||||
type ServerState = 'pending' | 'starting' | 'started' | 'error' | 'closed';
|
||||
|
||||
// defaultConfig should be used for testing only, and disables by default all features
|
||||
const defaultConfig: FlipperServerConfig = {
|
||||
androidHome: '',
|
||||
enableAndroid: false,
|
||||
serverPorts: {
|
||||
insecure: -1,
|
||||
secure: -1,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* FlipperServer takes care of all incoming device & client connections.
|
||||
* It will set up managers per device type, and create the incoming
|
||||
@@ -69,7 +69,10 @@ type ServerState = 'pending' | 'starting' | 'started' | 'error' | 'closed';
|
||||
* using '.on'. All events are strongly typed.
|
||||
*/
|
||||
export class FlipperServer {
|
||||
public config: FlipperServerConfig;
|
||||
|
||||
private readonly events = new EventEmitter();
|
||||
// server handles the incoming RSocket / WebSocket connections from Flipper clients
|
||||
readonly server: ServerController;
|
||||
readonly disposers: ((() => void) | void)[] = [];
|
||||
private readonly devices = new Map<string, BaseDevice>();
|
||||
@@ -78,60 +81,14 @@ export class FlipperServer {
|
||||
|
||||
// TODO: remove store argument
|
||||
constructor(
|
||||
public config: FlipperServerConfig,
|
||||
config: Partial<FlipperServerConfig>,
|
||||
/** @deprecated remove! */
|
||||
public store: Store,
|
||||
public logger: Logger,
|
||||
) {
|
||||
this.server = new ServerController(logger, store);
|
||||
this.config = {...defaultConfig, ...config};
|
||||
const server = (this.server = new ServerController(this));
|
||||
this.android = new AndroidDeviceManager(this);
|
||||
}
|
||||
|
||||
setServerState(state: ServerState, error?: Error) {
|
||||
this.state = state;
|
||||
this.emit('server-state', {state, error});
|
||||
}
|
||||
|
||||
async waitForServerStarted() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
switch (this.state) {
|
||||
case 'closed':
|
||||
return reject(new Error('Server was closed already'));
|
||||
case 'error':
|
||||
return reject(new Error('Server has errored already'));
|
||||
case 'started':
|
||||
return resolve();
|
||||
default: {
|
||||
const listener = ({
|
||||
state,
|
||||
error,
|
||||
}: {
|
||||
state: ServerState;
|
||||
error: Error;
|
||||
}) => {
|
||||
switch (state) {
|
||||
case 'error':
|
||||
return reject(error);
|
||||
case 'started':
|
||||
return resolve();
|
||||
case 'closed':
|
||||
return reject(new Error('Server closed'));
|
||||
}
|
||||
this.events.off('server-state', listener);
|
||||
};
|
||||
this.events.on('server-state', listener);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @private */
|
||||
async start() {
|
||||
if (this.state !== 'pending') {
|
||||
throw new Error('Server already started');
|
||||
}
|
||||
this.setServerState('starting');
|
||||
const server = this.server;
|
||||
|
||||
server.addListener('new-client', (client: Client) => {
|
||||
this.emit('client-connected', client);
|
||||
@@ -214,9 +171,24 @@ export class FlipperServer {
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setServerState(state: ServerState, error?: Error) {
|
||||
this.state = state;
|
||||
this.emit('server-state', {state, error});
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts listening to parts and watching for devices
|
||||
*/
|
||||
async start() {
|
||||
if (this.state !== 'pending') {
|
||||
throw new Error('Server already started');
|
||||
}
|
||||
this.setServerState('starting');
|
||||
|
||||
try {
|
||||
await server.init();
|
||||
await this.server.init();
|
||||
await this.startDeviceListeners();
|
||||
this.setServerState('started');
|
||||
} catch (e) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import ServerAdapter, {
|
||||
ServerEventsListener,
|
||||
} from './ServerAdapter';
|
||||
import {createBrowserServer, createServer} from './ServerFactory';
|
||||
import {FlipperServer} from '../FlipperServer';
|
||||
|
||||
type ClientInfo = {
|
||||
connection: ClientConnection | null | undefined;
|
||||
@@ -70,29 +71,38 @@ class ServerController extends EventEmitter implements ServerEventsListener {
|
||||
certificateProvider: CertificateProvider;
|
||||
connectionTracker: ConnectionTracker;
|
||||
|
||||
logger: Logger;
|
||||
store: Store;
|
||||
flipperServer: FlipperServer;
|
||||
|
||||
timeHandler: NodeJS.Timeout | undefined;
|
||||
|
||||
constructor(logger: Logger, store: Store) {
|
||||
constructor(flipperServer: FlipperServer) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.flipperServer = flipperServer;
|
||||
this.connections = new Map();
|
||||
this.certificateProvider = new CertificateProvider(
|
||||
this,
|
||||
logger,
|
||||
store.getState().settingsState,
|
||||
this.logger,
|
||||
this.store.getState().settingsState,
|
||||
);
|
||||
this.connectionTracker = new ConnectionTracker(logger);
|
||||
this.connectionTracker = new ConnectionTracker(this.logger);
|
||||
this.secureServer = null;
|
||||
this.insecureServer = null;
|
||||
this.browserServer = null;
|
||||
this.initialized = null;
|
||||
this.store = store;
|
||||
this.timeHandler = undefined;
|
||||
}
|
||||
|
||||
get logger(): Logger {
|
||||
return this.flipperServer.logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
get store(): Store {
|
||||
return this.flipperServer.store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the secure server configuration and starts any necessary servers.
|
||||
* Initialisation is complete once the initialized promise is fullfilled at
|
||||
@@ -117,7 +127,7 @@ class ServerController extends EventEmitter implements ServerEventsListener {
|
||||
reportPlatformFailures(this.initialized, 'initializeServer');
|
||||
|
||||
if (GK.get('flipper_js_client_emulator')) {
|
||||
initJsEmulatorIPC(this.store, this.logger, this, this.connections);
|
||||
initJsEmulatorIPC(this.flipperServer, this.connections);
|
||||
}
|
||||
|
||||
return this.initialized;
|
||||
|
||||
@@ -16,11 +16,8 @@ import {
|
||||
} from '../../comms/ClientConnection';
|
||||
import {ipcRenderer, remote, IpcRendererEvent} from 'electron';
|
||||
import JSDevice from './JSDevice';
|
||||
import {Store} from '../../../reducers';
|
||||
import {Logger} from '../../../fb-interfaces/Logger';
|
||||
import ServerController from '../../comms/ServerController';
|
||||
import {buildClientId} from '../../../utils/clientUtils';
|
||||
import {destroyDevice} from '../../../reducers/connections';
|
||||
import {FlipperServer} from '../../FlipperServer';
|
||||
|
||||
const connections: Map<number, JSClientFlipperConnection> = new Map();
|
||||
|
||||
@@ -31,9 +28,7 @@ function jsDeviceId(windowId: number): string {
|
||||
}
|
||||
|
||||
export function initJsEmulatorIPC(
|
||||
store: Store,
|
||||
logger: Logger,
|
||||
flipperServer: ServerController,
|
||||
flipperServer: FlipperServer,
|
||||
flipperConnections: Map<
|
||||
string,
|
||||
{
|
||||
@@ -48,10 +43,7 @@ export function initJsEmulatorIPC(
|
||||
const {windowId} = message;
|
||||
const {plugins, appName} = message.payload;
|
||||
const device = new JSDevice(jsDeviceId(windowId), 'jsEmulator', windowId);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: device,
|
||||
});
|
||||
flipperServer.registerDevice(device);
|
||||
|
||||
const connection = new JSClientFlipperConnection(windowId);
|
||||
connections.set(windowId, connection);
|
||||
@@ -70,8 +62,8 @@ export function initJsEmulatorIPC(
|
||||
clientId,
|
||||
query,
|
||||
connection,
|
||||
logger,
|
||||
store,
|
||||
flipperServer.logger,
|
||||
flipperServer.store,
|
||||
plugins,
|
||||
device,
|
||||
);
|
||||
@@ -87,8 +79,8 @@ export function initJsEmulatorIPC(
|
||||
status == ConnectionStatus.CLOSED
|
||||
) {
|
||||
console.debug(`Device disconnected ${client.id}`, 'server');
|
||||
flipperServer.removeConnection(client.id);
|
||||
destroyDevice(store, logger, jsDeviceId(windowId));
|
||||
flipperServer.server.removeConnection(client.id);
|
||||
flipperServer.unregisterDevice(jsDeviceId(windowId));
|
||||
connections.delete(windowId);
|
||||
availablePlugins.delete(windowId);
|
||||
}
|
||||
@@ -98,8 +90,8 @@ export function initJsEmulatorIPC(
|
||||
.init()
|
||||
.then(() => {
|
||||
console.log(client);
|
||||
flipperServer.emit('new-client', client);
|
||||
flipperServer.emit('clients-change');
|
||||
flipperServer.server.emit('new-client', client);
|
||||
flipperServer.server.emit('clients-change');
|
||||
client.emit('plugins-change');
|
||||
|
||||
ipcRenderer.on(
|
||||
|
||||
Reference in New Issue
Block a user