Intergrate ServerAddOn with PluginManager
Reviewed By: lblasa Differential Revision: D34042338 fbshipit-source-id: 2ae3992738e647075f19c4dba0ebfb01e6c12b8f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
016299b374
commit
a60865f0be
@@ -421,7 +421,7 @@ export class FlipperServerImpl implements FlipperServer {
|
|||||||
'plugin-source': (path) => this.pluginManager.loadSource(path),
|
'plugin-source': (path) => this.pluginManager.loadSource(path),
|
||||||
'plugins-server-add-on-start': (pluginName) =>
|
'plugins-server-add-on-start': (pluginName) =>
|
||||||
this.pluginManager.startServerAddOn(pluginName),
|
this.pluginManager.startServerAddOn(pluginName),
|
||||||
'plugins-server-add-on-stop': (pluginName) =>
|
'plugins-server-add-on-stop': async (pluginName) =>
|
||||||
this.pluginManager.stopServerAddOn(pluginName),
|
this.pluginManager.stopServerAddOn(pluginName),
|
||||||
'doctor-get-healthchecks': getHealthChecks,
|
'doctor-get-healthchecks': getHealthChecks,
|
||||||
'doctor-run-healthcheck': runHealthcheck,
|
'doctor-run-healthcheck': runHealthcheck,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
getInstalledPlugin,
|
getInstalledPlugin,
|
||||||
installPluginFromNpm,
|
installPluginFromNpm,
|
||||||
} from 'flipper-plugin-lib';
|
} from 'flipper-plugin-lib';
|
||||||
|
import {ServerAddOn} from './ServerAddOn';
|
||||||
|
|
||||||
const maxInstalledPluginVersionsToKeep = 2;
|
const maxInstalledPluginVersionsToKeep = 2;
|
||||||
|
|
||||||
@@ -43,6 +44,8 @@ const getTempDirName = promisify(tmp.dir) as (
|
|||||||
) => Promise<string>;
|
) => Promise<string>;
|
||||||
|
|
||||||
export class PluginManager {
|
export class PluginManager {
|
||||||
|
private readonly serverAddOns = new Map<string, ServerAddOn>();
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
// This needn't happen immediately and is (light) I/O work.
|
// This needn't happen immediately and is (light) I/O work.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -154,9 +157,32 @@ export class PluginManager {
|
|||||||
|
|
||||||
async startServerAddOn(pluginName: string) {
|
async startServerAddOn(pluginName: string) {
|
||||||
console.debug('PluginManager.startServerAddOn', pluginName);
|
console.debug('PluginManager.startServerAddOn', pluginName);
|
||||||
|
// TODO: Get owner from websocket connection ID
|
||||||
|
const fakeOwner = 'test';
|
||||||
|
const existingServerAddOn = this.serverAddOns.get(pluginName);
|
||||||
|
if (existingServerAddOn) {
|
||||||
|
console.debug(
|
||||||
|
'PluginManager.startServerAddOn -> already started, adding an owner',
|
||||||
|
pluginName,
|
||||||
|
fakeOwner,
|
||||||
|
);
|
||||||
|
existingServerAddOn.addOwner(fakeOwner);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopServerAddOn(pluginName: string) {
|
const newServerAddOn = await ServerAddOn.start(pluginName, fakeOwner);
|
||||||
|
this.serverAddOns.set(pluginName, newServerAddOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
stopServerAddOn(pluginName: string) {
|
||||||
console.debug('PluginManager.stopServerAddOn', pluginName);
|
console.debug('PluginManager.stopServerAddOn', pluginName);
|
||||||
|
const serverAddOn = this.serverAddOns.get(pluginName);
|
||||||
|
if (!serverAddOn) {
|
||||||
|
console.debug('PluginManager.stopServerAddOn -> not started', pluginName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: Get owner from websocket connection ID
|
||||||
|
const fakeOwner = 'test';
|
||||||
|
serverAddOn.removeOwner(fakeOwner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ interface ServerAddOnModule {
|
|||||||
serverAddOn?: () => Promise<ServerAddOnCleanup>;
|
serverAddOn?: () => Promise<ServerAddOnCleanup>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Metro does not like dynamic requires. Figure out how to properly configure metro to handle them.
|
||||||
|
// https://github.com/webpack/webpack/issues/4175#issuecomment-323023911
|
||||||
|
function requireDynamically(path: string) {
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
return eval(`require('${path}');`); // Ensure Metro does not analyze the require statement
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Fix potential race conditions when starting/stopping concurrently
|
// TODO: Fix potential race conditions when starting/stopping concurrently
|
||||||
export class ServerAddOn {
|
export class ServerAddOn {
|
||||||
private owners: Set<string>;
|
private owners: Set<string>;
|
||||||
@@ -30,7 +37,7 @@ export class ServerAddOn {
|
|||||||
static async start(path: string, initialOwner: string): Promise<ServerAddOn> {
|
static async start(path: string, initialOwner: string): Promise<ServerAddOn> {
|
||||||
console.info('ServerAddOn.start', path);
|
console.info('ServerAddOn.start', path);
|
||||||
|
|
||||||
const {serverAddOn} = require(path) as ServerAddOnModule;
|
const {serverAddOn} = requireDynamically(path) as ServerAddOnModule;
|
||||||
assertNotNull(serverAddOn);
|
assertNotNull(serverAddOn);
|
||||||
assert(
|
assert(
|
||||||
typeof serverAddOn === 'function',
|
typeof serverAddOn === 'function',
|
||||||
@@ -66,6 +73,10 @@ export class ServerAddOn {
|
|||||||
|
|
||||||
private async stop() {
|
private async stop() {
|
||||||
console.info('ServerAddOn.stop', this.path);
|
console.info('ServerAddOn.stop', this.path);
|
||||||
|
try {
|
||||||
await this.cleanup();
|
await this.cleanup();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('ServerAddOn.stop -> failed to clean up', this.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user