Skip to content

Commit

Permalink
Add optional module for performance measurements
Browse files Browse the repository at this point in the history
- Introduce an optional performance module that add performance measurements to core GLSP concepts.
- Performance is simply measured using console.time which also allows inspection of the tracked events in the dev tools trace viewer
- The module is opt-in and disabled by default. To enable it the &performance=true query parameter has to be added to the url
  • Loading branch information
tortmayr committed Oct 1, 2024
1 parent be065c0 commit 45c5681
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 4 deletions.
4 changes: 3 additions & 1 deletion integration/standalone/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const sourceUri = parameters.get('file') ?? '';
const select = parameters.get('select');
const theme = (parameters.get('theme') as ThemeMode) ?? SwitchThemeActionHandler.prefsColorScheme();
const debug = parameters.has('debug', 'true');
const measurePerformance = parameters.has('performance', 'true');

const id = 'ivy-glsp-process-editor';
const diagramType = 'ivy-glsp-process';
Expand Down Expand Up @@ -50,7 +51,8 @@ async function initialize(connectionProvider: MessageConnection, isReconnecting
app,
pmv,
server: webSocketBase
}
},
measurePerformance
});

const diagramLoader = container.get(DiagramLoader);
Expand Down
4 changes: 3 additions & 1 deletion integration/standalone/src/di.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createIvyDiagramContainer, ivyThemeModule } from '@axonivy/process-editor';
import { createIvyDiagramContainer, createPerformanceModule, ivyThemeModule } from '@axonivy/process-editor';
import { ivyInscriptionModule } from '@axonivy/process-editor-inscription';
import {
IDiagramOptions,
Expand All @@ -20,12 +20,14 @@ export interface IvyDiagramOptions extends IDiagramOptions {
select: string | null;
theme: ThemeMode;
inscriptionContext: InscriptionContext & { server: string };
measurePerformance?: boolean;
}

export default function createContainer(options: IvyDiagramOptions): Container {
const container = createIvyDiagramContainer(
'sprotty',
createDiagramOptionsModule(options),
createPerformanceModule(options.measurePerformance),
// standalone modules
standaloneSelectModule,
standaloneExportModule,
Expand Down
4 changes: 3 additions & 1 deletion integration/viewer/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const highlight = parameters.get('highlight') ?? '';
const select = parameters.get('select');
const zoom = parameters.get('zoom') ?? '';
const theme = (parameters.get('theme') as ThemeMode) ?? SwitchThemeActionHandler.prefsColorScheme();
const measurePerformance = parameters.has('performance', 'true');

const id = 'ivy-glsp-process-viewer';
const diagramType = 'ivy-glsp-process';
Expand All @@ -46,7 +47,8 @@ async function initialize(connectionProvider: MessageConnection, isReconnecting
highlight,
select,
zoom,
theme
theme,
measurePerformance
});

const diagramLoader = container.get(DiagramLoader);
Expand Down
3 changes: 3 additions & 0 deletions integration/viewer/src/di.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
createIvyDiagramContainer,
createPerformanceModule,
ivyChangeBoundsToolModule,
ivyConnectorModule,
ivyKeyListenerModule,
Expand Down Expand Up @@ -31,13 +32,15 @@ export interface IvyDiagramOptions extends IDiagramOptions {
select: string | null;
zoom: string;
theme: ThemeMode;
measurePerformance?: boolean;
}

export default function createContainer(options: IvyDiagramOptions): Container {
// ivyNavigationModule is a replacement for navigationModule but it is already removed in the default IvyDiagramContainer
const container = createIvyDiagramContainer(
'sprotty',
createDiagramOptionsModule(options),
createPerformanceModule(options.measurePerformance),
ivyThemeModule,
ivyNavigationModule,
ivyStartupDiagramModule,
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ export * from './ui-tools/viewport/viewport-bar';
export * from './key-listener/jump-out';
export * from './key-listener/quick-actions';
export * from './start-action/actions';

export * from './performance/performance-module';
export * from './ivy-glsp-jsonrpc-client';
23 changes: 23 additions & 0 deletions packages/editor/src/performance/perf-action-dispatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Action, GLSPActionDispatcher, RequestAction, ResponseAction } from '@eclipse-glsp/client';
import { injectable } from 'inversify';

@injectable()
export class PerfActionDispatcher extends GLSPActionDispatcher {
protected counter = 0;

override request<Res extends ResponseAction>(action: RequestAction<Res>): Promise<Res> {
const counter = ++this.counter;
console.time(`request-${action.kind}-${counter}`);
const result = super.request(action);
console.timeEnd(`request-${action.kind}-${counter}`);
this.counter++;
return result;
}

override async dispatch(action: Action): Promise<void> {
const counter = ++this.counter;
console.time(`dispatch-${action.kind}-${counter}`);
await super.dispatch(action);
console.timeEnd(`dispatch-${action.kind}-${counter}`);
}
}
23 changes: 23 additions & 0 deletions packages/editor/src/performance/perf-diagram-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DiagramLoader, IDiagramStartup, ResolvedDiagramLoadingOptions } from '@eclipse-glsp/client';
import { injectable } from 'inversify';

@injectable()
export class PerfDiagramLoader extends DiagramLoader {
protected override async invokeStartupHook(hook: keyof Omit<IDiagramStartup, 'rank'>): Promise<void> {
console.time('invokeStartupHook-' + hook);
await super.invokeStartupHook(hook);
console.timeEnd('invokeStartupHook-' + hook);
}

protected override async initialize(options: ResolvedDiagramLoadingOptions): Promise<void> {
console.time('DiagramLoader.initialize');
await super.initialize(options);
console.timeEnd('DiagramLoader.initialize');
}

protected override async requestModel(options: ResolvedDiagramLoadingOptions): Promise<void> {
console.time('DiagramLoader.requestModel');
await super.requestModel(options);
console.timeEnd('DiagramLoader.requestModel');
}
}
14 changes: 14 additions & 0 deletions packages/editor/src/performance/perf-viewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Action, GModelRoot, ModelViewer } from '@eclipse-glsp/client';
import { injectable } from 'inversify';

@injectable()
export class PerfModelViewer extends ModelViewer {
protected counter = 0;

update(model: Readonly<GModelRoot>, cause?: Action): void {
const counter = ++this.counter;
console.time('Viewer update ' + counter);
super.update(model, cause);
console.timeEnd('Viewer update ' + counter);
}
}
18 changes: 18 additions & 0 deletions packages/editor/src/performance/performance-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DiagramLoader, FeatureModule, GLSPActionDispatcher, TYPES } from '@eclipse-glsp/client';
import { PerfDiagramLoader } from './perf-diagram-loader';
import { PerfActionDispatcher } from './perf-action-dispatcher';
import { PerfModelViewer } from './perf-viewer';

export function createPerformanceModule(enabled?: boolean): FeatureModule {
return new FeatureModule(
(bind, unbind, isBound, rebind) => {
if (!enabled) {
return;
}
rebind(DiagramLoader).to(PerfDiagramLoader).inSingletonScope();
rebind(GLSPActionDispatcher).to(PerfActionDispatcher).inSingletonScope();
rebind(TYPES.ModelViewer).to(PerfModelViewer).inSingletonScope();
},
{ featureId: Symbol('performance') }
);
}

0 comments on commit 45c5681

Please sign in to comment.