Make sure devices and clients are registered on session startup

Summary: This diff makes sure that when the client starts, it fetches all known devices and clients first, as it might have missed the 'connect' events for those. For Electron this wasn't needed, since the server starts with the UI, but this makes sure that a browser reload or a second connection sees the same devices & apps

Reviewed By: aigoncharov

Differential Revision: D32881589

fbshipit-source-id: 7b1cb3d296044f83dedcf3f3d8d02864690b6666
This commit is contained in:
Michel Weststrate
2021-12-08 04:25:28 -08:00
committed by Facebook GitHub Bot
parent 943d535e86
commit 3c6668a8b9
3 changed files with 67 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ import {
Logger,
NoLongerConnectedToClientError,
isTest,
DeviceDescription,
} from 'flipper-common';
import Client from '../Client';
import {notification} from 'antd';
@@ -64,37 +65,7 @@ export function connectFlipperServerToStore(
});
server.on('device-connected', (deviceInfo) => {
logger.track('usage', 'register-device', {
os: deviceInfo.os,
name: deviceInfo.title,
serial: deviceInfo.serial,
});
const existing = store
.getState()
.connections.devices.find(
(device) => device.serial === deviceInfo.serial,
);
// handled outside reducer, as it might emit new redux actions...
if (existing) {
if (existing.connected.get()) {
console.warn(
`Tried to replace still connected device '${existing.serial}' with a new instance.`,
);
}
existing.destroy();
}
const device = new BaseDevice(server, deviceInfo);
device.loadDevicePlugins(
store.getState().plugins.devicePlugins,
store.getState().connections.enabledDevicePlugins,
);
store.dispatch({
type: 'REGISTER_DEVICE',
payload: device,
});
handleDeviceConnected(server, store, logger, deviceInfo);
});
server.on('device-disconnected', (device) => {
@@ -141,6 +112,26 @@ export function connectFlipperServerToStore(
'Flipper server started and accepting device / client connections',
);
server
.exec('device-list')
.then((devices) => {
// register all devices
devices.forEach((device) => {
handleDeviceConnected(server, store, logger, device);
});
})
.then(() => {
return server.exec('client-list');
})
.then((clients) => {
clients.forEach((client) => {
handleClientConnected(server, store, logger, client);
});
})
.catch((e) => {
console.error('Failed to get initial device/client list: ', e);
});
return () => {
sideEffectDisposer?.();
server.close();
@@ -182,6 +173,43 @@ function startSideEffects(store: Store, server: FlipperServer) {
};
}
function handleDeviceConnected(
server: FlipperServer,
store: Store,
logger: Logger,
deviceInfo: DeviceDescription,
) {
logger.track('usage', 'register-device', {
os: deviceInfo.os,
name: deviceInfo.title,
serial: deviceInfo.serial,
});
const existing = store
.getState()
.connections.devices.find((device) => device.serial === deviceInfo.serial);
// handled outside reducer, as it might emit new redux actions...
if (existing) {
if (existing.connected.get()) {
console.warn(
`Tried to replace still connected device '${existing.serial}' with a new instance.`,
);
}
existing.destroy();
}
const device = new BaseDevice(server, deviceInfo);
device.loadDevicePlugins(
store.getState().plugins.devicePlugins,
store.getState().connections.enabledDevicePlugins,
);
store.dispatch({
type: 'REGISTER_DEVICE',
payload: device,
});
}
export async function handleClientConnected(
server: Pick<FlipperServer, 'exec'>,
store: Store,