Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor server communication to JSON-RPC #990

Merged
merged 5 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions doc/adr/0002/graphql-server-prototype/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// [1] https://www.apollographql.com/docs/apollo-server/getting-started/#step-3-define-your-graphql-schema

const { ApolloServer, gql } = require('apollo-server');
const { TspClient } = require('tsp-typescript-client/lib/protocol/tsp-client');
const { HttpTspClient } = require('tsp-typescript-client/lib/protocol/http-tsp-client');

// A schema is a collection of type definitions (hence "typeDefs").
const typeDefs = gql`
Expand All @@ -21,7 +21,7 @@ const baseUrl = "http://localhost:8080/tsp/api";
const resolvers = {
Query: {
async status() {
const tspClient = new TspClient(baseUrl);
const tspClient = new HttpTspClient(baseUrl);
try {
const response = await tspClient.checkHealth();
if (response.isOk()) {
Expand All @@ -37,7 +37,7 @@ const resolvers = {
},
async traces() {
// Same simple approach as above. Returns how many traces only.
const tspClient = new TspClient(baseUrl);
const tspClient = new HttpTspClient(baseUrl);
try {
const response = await tspClient.fetchTraces();
if (response.isOk()) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"scripts": {
"prepare": "yarn -s tsref && yarn -s tsbuild && yarn -s download:plugins && yarn -s prepare:examples",
"prepare": "yarn -s clean && yarn -s tsref && yarn -s tsbuild && yarn -s download:plugins && yarn -s prepare:examples",
sgraband marked this conversation as resolved.
Show resolved Hide resolved
"tsref": "node scripts/typescript-references.js",
"tsbuild": "tsc -b",
"tswatch": "tsc -b -w",
Expand Down
11 changes: 7 additions & 4 deletions packages/base/src/experiment-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Trace } from 'tsp-typescript-client/lib/models/trace';
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { Query } from 'tsp-typescript-client/lib/models/query/query';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { Experiment } from 'tsp-typescript-client/lib/models/experiment';
Expand All @@ -9,10 +9,10 @@ import { signalManager, Signals } from './signals/signal-manager';

export class ExperimentManager {
private fOpenExperiments: Map<string, Experiment> = new Map();
private fTspClient: TspClient;
private fTspClient: ITspClient;
private fTraceManager: TraceManager;

constructor(tspClient: TspClient, traceManager: TraceManager) {
constructor(tspClient: ITspClient, traceManager: TraceManager) {
this.fTspClient = tspClient;
this.fTraceManager = traceManager;
signalManager().on(Signals.EXPERIMENT_DELETED, (experiment: Experiment) =>
Expand Down Expand Up @@ -79,7 +79,10 @@ export class ExperimentManager {
traceURIs.push(traces[i].UUID);
}

const tryCreate = async function (tspClient: TspClient, retry: number): Promise<TspClientResponse<Experiment>> {
const tryCreate = async function (
tspClient: ITspClient,
retry: number
): Promise<TspClientResponse<Experiment>> {
return tspClient.createExperiment(
new Query({
name: retry === 0 ? name : name + '(' + retry + ')',
Expand Down
30 changes: 21 additions & 9 deletions packages/base/src/lazy-tsp-client.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { TspClient } from 'tsp-typescript-client';
import { ITspClient } from 'tsp-typescript-client';
import { HttpTspClient } from 'tsp-typescript-client/lib/protocol/http-tsp-client';

/**
* Hack!
* The `LazyTspClient` replaces _every_ method with an asynchronous one.
* Only keep methods, discard properties.
*/
export type LazyTspClient = {
[K in keyof TspClient]: TspClient[K] extends (...args: infer A) => infer R | Promise<infer R>
[K in keyof ITspClient]: ITspClient[K] extends (...args: infer A) => infer R | Promise<infer R>
? (...args: A) => Promise<R>
: never; // Discard property.
};

export type LazyTspClientFactory = typeof LazyTspClientFactory;
export function LazyTspClientFactory(url: Promise<string>): TspClient {
// All methods from the `TspClient` are asynchronous. The `LazyTspClient`
export function LazyTspClientFactory(provider: () => Promise<string>): ITspClient {
// All methods from the `HttpTspClient` are asynchronous. The `LazyTspClient`
// will just delay each call to its methods by first awaiting for the
// asynchronous `baseUrl` resolution to then get a valid `TspClient`.
const tspClientPromise = url.then(baseUrl => new TspClient(baseUrl));
// asynchronous `baseUrl` resolution to then get a valid `HttpTspClient`.

// Save the current HttpTspClient and the URL used for it.
let tspClient: HttpTspClient;
let lastUrl: string;
// eslint-disable-next-line no-null/no-null
return new Proxy(Object.create(null), {
get(target, property, _receiver) {
let method = target[property];
if (!method) {
target[property] = method = async (...args: any[]) => {
const tspClient = (await tspClientPromise) as any;
return tspClient[property](...args);
tspClient = await provider().then(baseUrl => {
// If the url has not been updated keep the same client.
if (lastUrl === baseUrl) {
return tspClient;
}
// If the url has changed save it and create a new client.
lastUrl = baseUrl;
return new HttpTspClient(baseUrl);
});
return (tspClient as any)[property](...args);
};
}
return method;
}
}) as LazyTspClient as TspClient;
}) as LazyTspClient as ITspClient;
}
10 changes: 5 additions & 5 deletions packages/base/src/trace-manager.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Trace } from 'tsp-typescript-client/lib/models/trace';
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { Query } from 'tsp-typescript-client/lib/models/query/query';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { TspClientResponse } from 'tsp-typescript-client/lib/protocol/tsp-client-response';
import { signalManager } from './signals/signal-manager';

export class TraceManager {
private fOpenTraces: Map<string, Trace> = new Map();
private fTspClient: TspClient;
private fTspClient: ITspClient;

constructor(tspClient: TspClient) {
constructor(tspClient: ITspClient) {
this.fTspClient = tspClient;
}

Expand Down Expand Up @@ -69,7 +69,7 @@ export class TraceManager {
async openTrace(traceURI: string, traceName?: string): Promise<Trace | undefined> {
const name = traceName ? traceName : traceURI.replace(/\/$/, '').replace(/(.*\/)?/, '');

const tryOpen = async function (tspClient: TspClient, retry: number): Promise<TspClientResponse<Trace>> {
const tryOpen = async function (tspClient: ITspClient, retry: number): Promise<TspClientResponse<Trace>> {
return tspClient.openTrace(
new Query({
name: retry === 0 ? name : name + '(' + retry + ')',
Expand Down Expand Up @@ -103,7 +103,7 @@ export class TraceManager {
if (currentTrace) {
const traceResponse = await this.fTspClient.fetchTrace(currentTrace.UUID);
const trace = traceResponse.getModel();
if (trace && traceResponse.isOk) {
if (trace && traceResponse.isOk()) {
this.fOpenTraces.set(traceUUID, trace);
return trace;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/base/src/tsp-client-provider.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ExperimentManager } from './experiment-manager';
import { TraceManager } from './trace-manager';

export interface ITspClientProvider {
getTspClient(): TspClient;
getTspClient(): ITspClient;
getTraceManager(): TraceManager;
getExperimentManager(): ExperimentManager;
/**
* Add a listener for trace server url changes
* @param listener The listener function to be called when the url is
* changed
*/
addTspClientChangeListener(listener: (tspClient: TspClient) => void): void;
addTspClientChangeListener(listener: (tspClient: ITspClient) => void): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CellRenderer, LoadingRenderer, SearchFilterRenderer } from '../table-re
import { AbstractOutputProps } from '../abstract-output-component';
import { TimeGraphUnitController } from 'timeline-chart/lib/time-graph-unit-controller';
import { TimeRange } from 'traceviewer-base/lib/utils/time-range';
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { HttpTspClient } from 'tsp-typescript-client/lib/protocol/http-tsp-client';
import { ColDef, Column, ColumnApi, GridApi, IRowModel, RowNode } from 'ag-grid-community';

describe('<TableOutputComponent />', () => {
Expand Down Expand Up @@ -38,7 +38,7 @@ describe('<TableOutputComponent />', () => {
componentLeft: 0,
chartOffset: 0
},
tspClient: new TspClient('testURL'),
tspClient: new HttpTspClient('testURL'),
traceId: '0',
outputDescriptor: {
id: '0',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBars, faSpinner, faThumbtack, faTimes } from '@fortawesome/free-solid-svg-icons';
import { TimeGraphUnitController } from 'timeline-chart/lib/time-graph-unit-controller';
Expand All @@ -11,16 +11,10 @@ import { TooltipComponent } from './tooltip-component';
import { TooltipXYComponent } from './tooltip-xy-component';
import { ResponseStatus } from 'tsp-typescript-client/lib/models/response/responses';
import { signalManager } from 'traceviewer-base/lib/signals/signal-manager';
import {
DropDownComponent,
DropDownSubSection,
OptionCheckBoxState,
OptionState,
OptionType
} from './drop-down-component';
import { DropDownComponent, DropDownSubSection, OptionState } from './drop-down-component';

export interface AbstractOutputProps {
tspClient: TspClient;
tspClient: ITspClient;
tooltipComponent: TooltipComponent | null;
tooltipXYComponent: TooltipXYComponent | null;
traceId: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { QueryHelper } from 'tsp-typescript-client/lib/models/query/query-helper';
import { OutputStyleModel, OutputElementStyle } from 'tsp-typescript-client/lib/models/styles';
import { StyleProperties } from './style-properties';

export class StyleProvider {
private tspClient: TspClient;
private tspClient: ITspClient;
private traceId: string;
private outputId: string;

private tmpStyleObject: { [key: string]: { [key: string]: { [key: string]: any } } };

private styleModel: OutputStyleModel | undefined;

constructor(outputId: string, traceId: string, tspClient: TspClient) {
constructor(outputId: string, traceId: string, tspClient: ITspClient) {
this.outputId = outputId;
this.tspClient = tspClient;
this.traceId = traceId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import {
TimeGraphArrow,
TimeGraphEntry,
Expand All @@ -21,15 +21,15 @@ enum ElementType {
}

export class TspDataProvider {
private client: TspClient;
private client: ITspClient;
private outputId: string;
private traceUUID: string;
private timeGraphEntries: TimeGraphEntry[];
private timeGraphRows: TimeGraphRow[];

public totalRange: bigint;

constructor(client: TspClient, traceUUID: string, outputId: string) {
constructor(client: ITspClient, traceUUID: string, outputId: string) {
this.timeGraphEntries = [];
this.timeGraphRows = [];
this.client = client;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { TimelineChart } from 'timeline-chart/lib/time-graph-model';
import { TimeGraphUnitController } from 'timeline-chart/lib/time-graph-unit-controller';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { Experiment } from 'tsp-typescript-client/lib/models/experiment';
import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { TimeRange, TimeRangeString } from 'traceviewer-base/lib/utils/time-range';
import { TableOutputComponent } from './table-output-component';
import { TimegraphOutputComponent } from './timegraph-output-component';
Expand All @@ -34,7 +34,7 @@ import { TimeRangeUpdatePayload } from 'traceviewer-base/lib/signals/time-range-
const ResponsiveGridLayout = WidthProvider(Responsive);

export interface TraceContextProps {
tspClient: TspClient;
tspClient: ITspClient;
experiment: Experiment;
outputs: OutputDescriptor[];
overviewDescriptor?: OutputDescriptor; // The default output descriptor for the overview
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import { OutputDescriptor, TspClient } from 'tsp-typescript-client';
import { OutputDescriptor, ITspClient } from 'tsp-typescript-client';
import { AbstractDialogComponent, DialogComponentProps } from './abstract-dialog-component';
import { signalManager } from 'traceviewer-base/lib/signals/signal-manager';
import { AvailableViewsComponent } from './utils/available-views-component';

export interface TraceOverviewSelectionComponentProps extends DialogComponentProps {
tspClient: TspClient;
tspClient: ITspClient;
traceID: string;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { inject, injectable } from 'inversify';
import { PortPreferenceProxy } from '../common/trace-server-url-provider';
import { TracePreferences, TRACE_PORT } from './trace-server-preference';

@injectable()
export class PreferencesFrontendContribution implements FrontendApplicationContribution {
constructor(
@inject(TracePreferences) protected tracePreferences: TracePreferences,
@inject(PortPreferenceProxy) protected portPreferenceProxy: PortPreferenceProxy
) {}

async initialize(): Promise<void> {
this.tracePreferences.ready.then(() => {
this.portPreferenceProxy.onPortPreferenceChanged(this.tracePreferences[TRACE_PORT]);
this.tracePreferences.onPreferenceChanged(async event => {
if (event.preferenceName === TRACE_PORT) {
const newValue = typeof event.newValue === 'string' ? parseInt(event.newValue) : event.newValue;
const oldValue = typeof event.oldValue === 'string' ? parseInt(event.oldValue) : event.oldValue;
this.portPreferenceProxy.onPortPreferenceChanged(newValue, oldValue, true);
}
});
});
}
}
Loading
Loading