Make client -> device connection synchronous
Summary:
devices not always being readily available is causes a lot of complication in the api,
figured to resolve devices first before construction clients,
since clients not attached to a device are shown uncategorized anyway, making them practically un-interactable.
For more background info, see following chat.
{F344388883}
This diff will make it possible to only expose a synchronous api in Sandy
n.b. didn't update Navigation plugin, as that is done in a next diff
Reviewed By: jknoxville
Differential Revision: D24858332
fbshipit-source-id: 8339f831fbbc9c219add56a199364fde67adafc7
This commit is contained in:
committed by
Facebook GitHub Bot
parent
fd8065eb7a
commit
9b4e7e873c
@@ -21,7 +21,7 @@ import {setPluginState} from './reducers/pluginStates';
|
||||
import {Payload, ConnectionStatus} from 'rsocket-types';
|
||||
import {Flowable, Single} from 'rsocket-flowable';
|
||||
import {performance} from 'perf_hooks';
|
||||
import {reportPlatformFailures, reportPluginFailures} from './utils/metrics';
|
||||
import {reportPluginFailures} from './utils/metrics';
|
||||
import {notNull} from './utils/typeUtils';
|
||||
import {default as isProduction} from './utils/isProduction';
|
||||
import {registerPlugins} from './reducers/plugins';
|
||||
@@ -33,7 +33,6 @@ import {
|
||||
defaultEnabledBackgroundPlugins,
|
||||
} from './utils/pluginUtils';
|
||||
import {processMessagesLater} from './utils/messageQueue';
|
||||
import {sideEffect} from './utils/sideEffect';
|
||||
import {emitBytesReceived} from './dispatcher/tracking';
|
||||
import {debounce} from 'lodash';
|
||||
import {batch} from 'react-redux';
|
||||
@@ -134,11 +133,14 @@ export default class Client extends EventEmitter {
|
||||
connection: FlipperClientConnection<any, any> | null | undefined;
|
||||
store: Store;
|
||||
activePlugins: Set<string>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use plugin.deviceSync instead
|
||||
*/
|
||||
device: Promise<BaseDevice>;
|
||||
_deviceResolve: (device: BaseDevice) => void = (_) => {};
|
||||
_deviceResolved: BaseDevice | undefined;
|
||||
deviceSync: BaseDevice;
|
||||
logger: Logger;
|
||||
lastSeenDeviceList: Array<BaseDevice>;
|
||||
broadcastCallbacks: Map<string, Map<string, Set<Function>>>;
|
||||
messageBuffer: Record<
|
||||
string /*pluginKey*/,
|
||||
@@ -168,8 +170,8 @@ export default class Client extends EventEmitter {
|
||||
conn: FlipperClientConnection<any, any> | null | undefined,
|
||||
logger: Logger,
|
||||
store: Store,
|
||||
plugins?: Plugins | null | undefined,
|
||||
device?: BaseDevice,
|
||||
plugins: Plugins | null | undefined,
|
||||
device: BaseDevice,
|
||||
) {
|
||||
super();
|
||||
this.connected = true;
|
||||
@@ -185,17 +187,9 @@ export default class Client extends EventEmitter {
|
||||
this.broadcastCallbacks = new Map();
|
||||
this.requestCallbacks = new Map();
|
||||
this.activePlugins = new Set();
|
||||
this.lastSeenDeviceList = [];
|
||||
|
||||
this.device = device
|
||||
? Promise.resolve(device)
|
||||
: new Promise((resolve, _reject) => {
|
||||
this._deviceResolve = resolve;
|
||||
});
|
||||
|
||||
if (device != null) {
|
||||
this._deviceResolved = device;
|
||||
}
|
||||
this.device = Promise.resolve(device);
|
||||
this.deviceSync = device;
|
||||
|
||||
const client = this;
|
||||
if (conn) {
|
||||
@@ -215,58 +209,6 @@ export default class Client extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/* All clients should have a corresponding Device in the store.
|
||||
However, clients can connect before a device is registered, so wait a
|
||||
while for the device to be registered if it isn't already. */
|
||||
async setMatchingDevice(): Promise<void> {
|
||||
return reportPlatformFailures(
|
||||
new Promise<BaseDevice>((resolve, reject) => {
|
||||
let unsubscribe: () => void = () => {};
|
||||
|
||||
const device = this.store
|
||||
.getState()
|
||||
.connections.devices.find(
|
||||
(device) => device.serial === this.query.device_id,
|
||||
);
|
||||
if (device) {
|
||||
this._deviceResolved = device;
|
||||
resolve(device);
|
||||
return;
|
||||
}
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
unsubscribe();
|
||||
const error = `Timed out waiting for device for client ${this.id}`;
|
||||
console.error(error);
|
||||
reject(error);
|
||||
}, 5000);
|
||||
unsubscribe = sideEffect(
|
||||
this.store,
|
||||
{name: 'waitForDevice', throttleMs: 100},
|
||||
(state) => state.connections.devices,
|
||||
(newDeviceList) => {
|
||||
if (newDeviceList === this.lastSeenDeviceList) {
|
||||
return;
|
||||
}
|
||||
this.lastSeenDeviceList = newDeviceList;
|
||||
const matchingDevice = newDeviceList.find(
|
||||
(device) => device.serial === this.query.device_id,
|
||||
);
|
||||
if (matchingDevice) {
|
||||
clearTimeout(timeout);
|
||||
resolve(matchingDevice);
|
||||
unsubscribe();
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
'client-setMatchingDevice',
|
||||
).then((device) => {
|
||||
this._deviceResolved = device;
|
||||
this._deviceResolve(device);
|
||||
});
|
||||
}
|
||||
|
||||
supportsPlugin(pluginId: string): boolean {
|
||||
return this.plugins.includes(pluginId);
|
||||
}
|
||||
@@ -289,7 +231,6 @@ export default class Client extends EventEmitter {
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.setMatchingDevice();
|
||||
await this.loadPlugins();
|
||||
// this starts all sandy enabled plugins
|
||||
this.plugins.forEach((pluginId) =>
|
||||
@@ -434,20 +375,12 @@ export default class Client extends EventEmitter {
|
||||
this.emit('plugins-change');
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use deviceSync.serial
|
||||
*/
|
||||
async deviceSerial(): Promise<string> {
|
||||
try {
|
||||
const device = await this.device;
|
||||
if (!device) {
|
||||
console.error('Using "" for deviceId device is not ready');
|
||||
return '';
|
||||
}
|
||||
return device.serial;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Using "" for deviceId because client has no matching device',
|
||||
);
|
||||
return '';
|
||||
}
|
||||
return this.deviceSync.serial;
|
||||
}
|
||||
|
||||
onMessage(msg: string) {
|
||||
@@ -478,7 +411,7 @@ export default class Client extends EventEmitter {
|
||||
flipperMessagesClientPlugin.isConnected()
|
||||
) {
|
||||
flipperMessagesClientPlugin.newMessage({
|
||||
device: this._deviceResolved?.displayTitle(),
|
||||
device: this.deviceSync?.displayTitle(),
|
||||
app: this.query.app,
|
||||
flipperInternalMethod: method,
|
||||
plugin: data.params?.api,
|
||||
@@ -497,7 +430,7 @@ export default class Client extends EventEmitter {
|
||||
}: ${error.message} + \nDevice Stack Trace: ${error.stacktrace}`,
|
||||
'deviceError',
|
||||
);
|
||||
this.device.then((device) => handleError(this.store, device, error));
|
||||
handleError(this.store, this.deviceSync, error);
|
||||
} else if (method === 'refreshPlugins') {
|
||||
this.refreshPlugins();
|
||||
} else if (method === 'execute') {
|
||||
@@ -576,7 +509,7 @@ export default class Client extends EventEmitter {
|
||||
reject(data.error);
|
||||
const {error} = data;
|
||||
if (error) {
|
||||
this.device.then((device) => handleError(this.store, device, error));
|
||||
handleError(this.store, this.deviceSync, error);
|
||||
}
|
||||
} else {
|
||||
// ???
|
||||
@@ -670,7 +603,7 @@ export default class Client extends EventEmitter {
|
||||
|
||||
if (flipperMessagesClientPlugin.isConnected()) {
|
||||
flipperMessagesClientPlugin.newMessage({
|
||||
device: this._deviceResolved?.displayTitle(),
|
||||
device: this.deviceSync?.displayTitle(),
|
||||
app: this.query.app,
|
||||
flipperInternalMethod: method,
|
||||
payload: response,
|
||||
@@ -692,7 +625,7 @@ export default class Client extends EventEmitter {
|
||||
|
||||
if (flipperMessagesClientPlugin.isConnected()) {
|
||||
flipperMessagesClientPlugin.newMessage({
|
||||
device: this._deviceResolved?.displayTitle(),
|
||||
device: this.deviceSync?.displayTitle(),
|
||||
app: this.query.app,
|
||||
flipperInternalMethod: method,
|
||||
plugin: params?.api,
|
||||
@@ -776,7 +709,7 @@ export default class Client extends EventEmitter {
|
||||
|
||||
if (flipperMessagesClientPlugin.isConnected()) {
|
||||
flipperMessagesClientPlugin.newMessage({
|
||||
device: this._deviceResolved?.displayTitle(),
|
||||
device: this.deviceSync?.displayTitle(),
|
||||
app: this.query.app,
|
||||
flipperInternalMethod: method,
|
||||
payload: params,
|
||||
|
||||
Reference in New Issue
Block a user