Skip to content

Commit

Permalink
Open multiple traces in same electron application (#9)
Browse files Browse the repository at this point in the history
* make port customizable via globals

Co-authored-by: Christian W. Damus <[email protected]>
  • Loading branch information
jfaltermeier and cdamus authored Jun 30, 2023
1 parent b9274d5 commit 3048bb7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 14 deletions.
23 changes: 15 additions & 8 deletions ui/src/common/http_rpc_engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import {StatusResult} from '../common/protos';

import {Engine, LoadingTracker} from './engine';

export const RPC_URL = 'http://127.0.0.1:9001/';
export const WS_URL = 'ws://127.0.0.1:9001/websocket';

const RPC_CONNECT_TIMEOUT_MS = 2000;

export function getRPC_URL(port: number) {
return `http://127.0.0.1:${port}/`;
}

export function getWS_URL(port: number) {
return `ws://127.0.0.1:${port}/websocket`;
}

export interface HttpRpcState {
connected: boolean;
status?: StatusResult;
Expand All @@ -34,20 +39,22 @@ export type HttpRcpEngineCustomizer = (engine: HttpRpcEngine) => unknown;

export class HttpRpcEngine extends Engine {
readonly id: string;
readonly port: number;
errorHandler: (err: string) => void = () => {};
closeHandler: (code: number, reason: string) => void = (code, reason) => this.errorHandler(`Websocket closed (${code}: ${reason})`);
private requestQueue = new Array<Uint8Array>();
private websocket?: WebSocket;
private connected = false;

constructor(id: string, loadingTracker?: LoadingTracker) {
constructor(id: string, loadingTracker?: LoadingTracker, port = 9001) {
super(loadingTracker);
this.id = id;
this.port = port;
}

rpcSendRequestBytes(data: Uint8Array): void {
if (this.websocket === undefined) {
this.websocket = new WebSocket(WS_URL);
this.websocket = new WebSocket(getWS_URL(this.port));
this.websocket.onopen = () => this.onWebsocketConnected();
this.websocket.onmessage = (e) => this.onWebsocketMessage(e);
this.websocket.onclose = (e) =>
Expand Down Expand Up @@ -78,15 +85,15 @@ export class HttpRpcEngine extends Engine {
});
}

static async checkConnection(): Promise<HttpRpcState> {
static async checkConnection(port: number): Promise<HttpRpcState> {
const httpRpcState: HttpRpcState = {connected: false};
console.info(
`It's safe to ignore the ERR_CONNECTION_REFUSED on ${RPC_URL} below. ` +
`It's safe to ignore the ERR_CONNECTION_REFUSED on ${getRPC_URL(port)} below. ` +
`That might happen while probing the external native accelerator. The ` +
`error is non-fatal and unlikely to be the culprit for any UI bug.`);
try {
const resp = await fetchWithTimeout(
RPC_URL + 'status',
getRPC_URL(port) + 'status',
{method: 'post', cache: 'no-cache'},
RPC_CONNECT_TIMEOUT_MS);
if (resp.status !== 200) {
Expand Down
4 changes: 2 additions & 2 deletions ui/src/controller/trace_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,13 @@ export class TraceController extends Controller<States> {
let engineMode: EngineMode;
let useRpc = false;
if (globals.state.newEngineMode === 'USE_HTTP_RPC_IF_AVAILABLE') {
useRpc = (await HttpRpcEngine.checkConnection()).connected;
useRpc = (await HttpRpcEngine.checkConnection(globals.httpRpcEnginePort)).connected;
}
let engine;
if (useRpc) {
console.log('Opening trace using native accelerator over HTTP+RPC');
engineMode = 'HTTP_RPC';
engine = new HttpRpcEngine(this.engineId, LoadingManager.getInstance);
engine = new HttpRpcEngine(this.engineId, LoadingManager.getInstance, globals.httpRpcEnginePort);
engine.errorHandler = (err) => {
globals.dispatch(
Actions.setEngineFailed({mode: 'HTTP_RPC', failure: `${err}`}));
Expand Down
9 changes: 9 additions & 0 deletions ui/src/frontend/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class Globals {
private _errorHandler: ErrorHandler = maybeShowErrorDialog;
private _allowFileDrop = true;
private _httpRpcEngineCustomizer?: HttpRcpEngineCustomizer;
private _httpRpcEnginePort = 9001;
private _promptToLoadFromTraceProcessorShell = true;
private _trackFilteringEnabled = false;
private _filteredTracks: AddTrackLikeArgs[] = [];
Expand Down Expand Up @@ -667,6 +668,14 @@ class Globals {
this._httpRpcEngineCustomizer = httpRpcEngineCustomizer;
}

get httpRpcEnginePort(): number {
return this._httpRpcEnginePort;
}

set httpRpcEnginePort(httpRpcEnginePort: number) {
this._httpRpcEnginePort = httpRpcEnginePort;
}

get promptToLoadFromTraceProcessorShell(): boolean {
return this._promptToLoadFromTraceProcessorShell;
}
Expand Down
8 changes: 4 additions & 4 deletions ui/src/frontend/rpc_http_dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import m from 'mithril';

import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {HttpRpcEngine, RPC_URL} from '../common/http_rpc_engine';
import {HttpRpcEngine, getRPC_URL} from '../common/http_rpc_engine';
import {StatusResult} from '../common/protos';
import {VERSION} from '../gen/perfetto_version';
import {perfetto} from '../gen/protos';
Expand All @@ -27,7 +27,7 @@ import {showModal} from './modal';
const CURRENT_API_VERSION = perfetto.protos.TraceProcessorApiVersion
.TRACE_PROCESSOR_CURRENT_API_VERSION;

const PROMPT = `Trace Processor Native Accelerator detected on ${RPC_URL} with:
const PROMPT = `Trace Processor Native Accelerator detected on ${getRPC_URL(globals.httpRpcEnginePort)} with:
$loadedTraceName
YES, use loaded trace:
Expand All @@ -50,7 +50,7 @@ too old. Get the latest version from get.perfetto.dev/trace_processor.
`;


const MSG_TOO_OLD = `The Trace Processor instance on ${RPC_URL} is too old.
const MSG_TOO_OLD = `The Trace Processor instance on ${getRPC_URL(globals.httpRpcEnginePort)} is too old.
This UI requires TraceProcessor features that are not present in the
Trace Processor native accelerator you are currently running.
Expand Down Expand Up @@ -79,7 +79,7 @@ let forceUseOldVersion = false;
// consistent UX (i.e. so that the user can tell if the RPC is working without
// having to open a trace).
export async function CheckHttpRpcConnection(): Promise<void> {
const state = await HttpRpcEngine.checkConnection();
const state = await HttpRpcEngine.checkConnection(globals.httpRpcEnginePort);
globals.frontendLocalState.setHttpRpcState(state);
if (!state.connected) return;
const tpStatus = assertExists(state.status);
Expand Down

0 comments on commit 3048bb7

Please sign in to comment.