From 228de6c5424716c00df7690002ea9a42ec9734a7 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Fri, 23 Sep 2022 10:20:53 -0700 Subject: [PATCH] Add custom timeout to Device.installApp Reviewed By: lblasa Differential Revision: D39728545 fbshipit-source-id: be77a2e7ddac4071c9cafc88e67b793ee8c7631c --- desktop/flipper-common/src/server-types.tsx | 8 ++++ .../src/client/FlipperServerClient.tsx | 26 ++++++++++- .../src/devices/BaseDevice.tsx | 19 +++++--- .../src/plugin/DevicePlugin.tsx | 2 +- .../src/FlipperServerImpl.tsx | 45 ++++++++++++++++++- 5 files changed, 89 insertions(+), 11 deletions(-) diff --git a/desktop/flipper-common/src/server-types.tsx b/desktop/flipper-common/src/server-types.tsx index 94bff7361..5c7c5e65a 100644 --- a/desktop/flipper-common/src/server-types.tsx +++ b/desktop/flipper-common/src/server-types.tsx @@ -470,6 +470,9 @@ export type FlipperServerConfig = { type?: FlipperServerType; }; +export interface FlipperServerExecOptions { + timeout: number; +} export interface FlipperServer { connect(): Promise; on( @@ -480,6 +483,11 @@ export interface FlipperServer { event: Event, callback: (payload: FlipperServerEvents[Event]) => void, ): void; + exec( + options: FlipperServerExecOptions, + event: Event, + ...args: Parameters + ): ReturnType; exec( event: Event, ...args: Parameters diff --git a/desktop/flipper-frontend-core/src/client/FlipperServerClient.tsx b/desktop/flipper-frontend-core/src/client/FlipperServerClient.tsx index c5bbcf52c..282876692 100644 --- a/desktop/flipper-frontend-core/src/client/FlipperServerClient.tsx +++ b/desktop/flipper-frontend-core/src/client/FlipperServerClient.tsx @@ -11,6 +11,8 @@ import EventEmitter from 'eventemitter3'; import { ExecWebSocketMessage, FlipperServer, + FlipperServerCommands, + FlipperServerExecOptions, ServerWebSocketMessage, } from 'flipper-common'; import ReconnectingWebSocket from 'reconnecting-websocket'; @@ -127,10 +129,30 @@ export function createFlipperServerWithSocket( } }); + const commandOrOptionsIsOptions = ( + commandOrOptions: FlipperServerExecOptions | string, + ): commandOrOptions is FlipperServerExecOptions => + typeof commandOrOptions === 'object'; + const flipperServer: FlipperServer = { async connect() {}, close() {}, - exec(command, ...args): any { + exec(commandOrOptions, ...argsAmbiguous): any { + let timeout: number; + let command: string; + let args: Parameters< + FlipperServerCommands[keyof FlipperServerCommands] + >; + if (commandOrOptionsIsOptions(commandOrOptions)) { + timeout = commandOrOptions.timeout; + command = argsAmbiguous[0] as string; + args = argsAmbiguous.slice(1) as typeof args; + } else { + timeout = EXEC_TIMEOUT; + command = commandOrOptions; + args = argsAmbiguous as typeof args; + } + if (connected) { const id = ++requestId; return new Promise((resolve, reject) => { @@ -144,7 +166,7 @@ export function createFlipperServerWithSocket( reject( new Error(`flipper-server: timeout for command '${command}'`), ); - }, EXEC_TIMEOUT), + }, timeout), }); const execMessage = { diff --git a/desktop/flipper-frontend-core/src/devices/BaseDevice.tsx b/desktop/flipper-frontend-core/src/devices/BaseDevice.tsx index abaa60585..8bfafcc3d 100644 --- a/desktop/flipper-frontend-core/src/devices/BaseDevice.tsx +++ b/desktop/flipper-frontend-core/src/devices/BaseDevice.tsx @@ -239,12 +239,19 @@ export default class BaseDevice implements Device { return this.flipperServer.exec('device-navigate', this.serial, location); } - async installApp(appBundlePath: string): Promise { - return this.flipperServer.exec( - 'device-install-app', - this.serial, - appBundlePath, - ); + async installApp(appBundlePath: string, timeout?: number): Promise { + return timeout + ? this.flipperServer.exec( + {timeout}, + 'device-install-app', + this.serial, + appBundlePath, + ) + : this.flipperServer.exec( + 'device-install-app', + this.serial, + appBundlePath, + ); } async screenshot(): Promise { diff --git a/desktop/flipper-plugin-core/src/plugin/DevicePlugin.tsx b/desktop/flipper-plugin-core/src/plugin/DevicePlugin.tsx index 1b0bd1616..0e49c166f 100644 --- a/desktop/flipper-plugin-core/src/plugin/DevicePlugin.tsx +++ b/desktop/flipper-plugin-core/src/plugin/DevicePlugin.tsx @@ -44,7 +44,7 @@ export interface Device { sendMetroCommand(command: string): Promise; navigateToLocation(location: string): Promise; screenshot(): Promise; - installApp(appBundlePath: string): Promise; + installApp(appBundlePath: string, timeout?: number): Promise; } export type DevicePluginPredicate = (device: Device) => boolean; diff --git a/desktop/flipper-server-core/src/FlipperServerImpl.tsx b/desktop/flipper-server-core/src/FlipperServerImpl.tsx index e7014cc72..0068a70b1 100644 --- a/desktop/flipper-server-core/src/FlipperServerImpl.tsx +++ b/desktop/flipper-server-core/src/FlipperServerImpl.tsx @@ -24,6 +24,7 @@ import { UninitializedClient, FlipperServerConfig, Logger, + FlipperServerExecOptions, } from 'flipper-common'; import {ServerDevice} from './devices/ServerDevice'; import {Base64} from 'js-base64'; @@ -268,14 +269,54 @@ export class FlipperServerImpl implements FlipperServer { this.events.emit('*', event, payload); } + private isExecWithOptions( + argsAmbiguous: + | [ + FlipperServerExecOptions, + Event, + ...Parameters, + ] + | [Event, ...Parameters], + ): argsAmbiguous is [ + FlipperServerExecOptions, + Event, + ...Parameters, + ] { + return typeof argsAmbiguous[0] === 'object'; + } + + exec( + options: FlipperServerExecOptions, + event: Event, + ...args: Parameters + ): ReturnType; exec( event: Event, ...args: Parameters ): ReturnType; async exec( - event: Event, - ...args: any[] + ...argsAmbiguous: + | [ + FlipperServerExecOptions, + Event, + ...Parameters, + ] + | [Event, ...Parameters] ): Promise { + let _timeout: number; + let event: Event; + let args: Parameters; + if (this.isExecWithOptions(argsAmbiguous)) { + _timeout = argsAmbiguous[0].timeout; + event = argsAmbiguous[1]; + args = argsAmbiguous.slice(2) as typeof args; + } else { + // _timeout is currently not used, so we are setting it to a random value. Update it to a meaningful timeout before using it! + _timeout = 42; + event = argsAmbiguous[0]; + args = argsAmbiguous.slice(1) as typeof args; + } + try { const handler: (...args: any[]) => Promise = this.commandHandler[event];