Skip to content

Commit

Permalink
fix: Avoid calling buildDiagram on seq diagram load
Browse files Browse the repository at this point in the history
This improves the load time of sequence diagrams by about 46%
  • Loading branch information
ahtrotta committed Oct 4, 2023
1 parent 83ad8f2 commit 3f5d737
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 29 deletions.
6 changes: 2 additions & 4 deletions packages/components/src/components/DiagramSequence.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
Diagram,
Specification,
Action,
getActors,
} from '@appland/sequence-diagram';
import VLoopAction from '@/components/sequence/LoopAction.vue';
import VCallAction from '@/components/sequence/CallAction.vue';
Expand Down Expand Up @@ -121,11 +122,8 @@ export default {
let { appMap } = this.$store.state;
if (!appMap) appMap = this.appMap;
// TODO: optimize for performance building actor priority separately
const specification = Specification.build(appMap, { loops: true });
const diagram = buildDiagram('<an AppMap file>', appMap, specification);
return diagram.actors;
return getActors(appMap, specification);
},
priority() {
const priority = {};
Expand Down
62 changes: 39 additions & 23 deletions packages/sequence-diagram/src/buildDiagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,52 @@ import {

const MAX_WINDOW_SIZE = 5;

export default function buildDiagram(
_appmapFile: string,
appmap: AppMap,
specification: Specification
): Diagram {
const events = selectEvents(appmap, specification);
class ActorManager {
private _actorsByCodeObjectId = new Map<string, Actor>();
private _actors: Actor[] = [];

const actors: Actor[] = [];
const actorsByCodeObjectId = new Map<string, Actor>();
constructor(private specification: Specification) {}

const findOrCreateActor = (event: Event): Actor | undefined => {
const actorCodeObject = specification.isIncludedCodeObject(event.codeObject);
findOrCreateActor(event: Event): Actor | undefined {
const actorCodeObject = this.specification.isIncludedCodeObject(event.codeObject);
if (!actorCodeObject) throw Error('actor code object not found');
const order = specification.priorityOf(actorCodeObject);
const order = this.specification.priorityOf(actorCodeObject);

const actorKey = actorCodeObject.fqid;

let actor = actorsByCodeObjectId.get(actorKey);
let actor = this._actorsByCodeObjectId.get(actorKey);
if (actor) return actor;

actor = {
id: actorCodeObject.fqid,
name: actorCodeObject.name,
order,
} as Actor;
actors.push(actor);
actorsByCodeObjectId.set(actorKey, actor);
this._actors.push(actor);
this._actorsByCodeObjectId.set(actorKey, actor);
return actor;
};
}

getSortedActors(): Actor[] {
return this._actors.sort((a, b) => a.order - b.order);
}
}

export default function buildDiagram(
_appmapFile: string,
appmap: AppMap,
specification: Specification
): Diagram {
const events = selectEvents(appmap, specification);
const actorManager = new ActorManager(specification);

function buildRequest(caller?: Event | undefined, callee?: Event): Action | undefined {
if (callee?.httpServerRequest && callee?.httpServerResponse) {
if (!callee.route) throw Error('callee.route not found');
const response = callee.httpServerResponse as any;
return {
nodeType: NodeType.ServerRPC,
callee: findOrCreateActor(callee),
callee: actorManager.findOrCreateActor(callee),
route: callee.route,
status: response.status || response.status_code,
digest: callee.hash,
Expand All @@ -70,8 +79,8 @@ export default function buildDiagram(
const response = callee.httpClientResponse as any;
return {
nodeType: NodeType.ClientRPC,
caller: caller ? findOrCreateActor(caller) : undefined,
callee: findOrCreateActor(callee),
caller: caller ? actorManager.findOrCreateActor(caller) : undefined,
callee: actorManager.findOrCreateActor(callee),
route: callee.route,
status: response.status || response.status_code,
digest: callee.hash,
Expand All @@ -84,8 +93,8 @@ export default function buildDiagram(
const truncatedQuery = callee.sqlQuery.endsWith('...');
return {
nodeType: NodeType.Query,
caller: caller ? findOrCreateActor(caller) : undefined,
callee: findOrCreateActor(callee),
caller: caller ? actorManager.findOrCreateActor(caller) : undefined,
callee: actorManager.findOrCreateActor(callee),
query: callee.sqlQuery,
digest: truncatedQuery ? 'truncatedQuery' : callee.hash,
subtreeDigest: 'undefined',
Expand All @@ -96,8 +105,8 @@ export default function buildDiagram(
} else if (callee) {
return {
nodeType: NodeType.Function,
caller: caller ? findOrCreateActor(caller) : undefined,
callee: findOrCreateActor(callee),
caller: caller ? actorManager.findOrCreateActor(caller) : undefined,
callee: actorManager.findOrCreateActor(callee),
name: callee.codeObject.name,
static: callee.codeObject.static,
digest: callee.hash,
Expand Down Expand Up @@ -216,7 +225,14 @@ export default function buildDiagram(
rootActions.forEach((root) => setParent(root));

return {
actors: actors.sort((a, b) => a.order - b.order),
actors: actorManager.getSortedActors(),
rootActions,
};
}

export function getActors(appmap: AppMap, specification: Specification): Actor[] {
const actorManager = new ActorManager(specification);
const events = selectEvents(appmap, specification);
events.forEach((event) => actorManager.findOrCreateActor(event));
return actorManager.getSortedActors();
}
4 changes: 2 additions & 2 deletions packages/sequence-diagram/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ export enum ValidationResult {
AppMap = 2,
}

import buildDiagram from './buildDiagram';
import buildDiagram, { getActors } from './buildDiagram';
import buildDiffDiagram from './buildDiffDiagram';
import diff from './diff';
import unparseDiagram from './unparseDiagram';
import validateDiagram from './validateDiagram';
export { buildDiagram, buildDiffDiagram, diff, unparseDiagram, validateDiagram };
export { buildDiagram, buildDiffDiagram, diff, unparseDiagram, validateDiagram, getActors };

export enum FormatType {
JSON = 'json',
Expand Down

0 comments on commit 3f5d737

Please sign in to comment.