Skip to content

Commit 03afa4d

Browse files
CurryYangxxgatzjamesjackkav
authored
perf: improve performance when spec lint [INS-3724] (#7374)
* perf: spec lint * Move ruleset loading to main * fix: solve todo * fix: solve todo * feat: open nodeIntegrationInWorker option * fix: need save spectralRun ipc * feat: add worker plugin * put the default ruleset handling in loadSpectralRuleset * make sure we check for latest id * fix: postMessage and ipc can not transfer special objects * move logic to new place and clean up main * fix race condition and cleanup code * fix: worker build * add necessary worker ternminate and more logs * use fs require in worker * rename file and add reject * fix typo * remove unused console log in loader * leave note about GC --------- Co-authored-by: gatzjames <jamesgatzos@gmail.com> Co-authored-by: jackkav <jackkav@gmail.com>
1 parent bb7916c commit 03afa4d

13 files changed

Lines changed: 374 additions & 260 deletions

File tree

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/insomnia/esbuild.main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export default async function build(options: Options) {
5858
'.node': 'copy',
5959
},
6060
});
61+
6162
const main = esbuild.build({
6263
entryPoints: ['./src/main.development.ts'],
6364
outfile: path.join(outdir, 'main.min.js'),

packages/insomnia/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@
4646
"@seald-io/nedb": "^4.0.4",
4747
"@segment/analytics-node": "2.1.0",
4848
"@sentry/electron": "^3.0.7",
49-
"@stoplight/spectral-core": "^1.18.3",
50-
"@stoplight/spectral-formats": "^1.6.0",
51-
"@stoplight/spectral-ruleset-bundler": "1.5.2",
52-
"@stoplight/spectral-rulesets": "^1.18.1",
5349
"apiconnect-wsdl": "1.8.31",
5450
"aws4": "^1.12.0",
5551
"chai": "^4.3.4",
@@ -87,6 +83,10 @@
8783
"yaml-source-map": "^2.1.1"
8884
},
8985
"devDependencies": {
86+
"@stoplight/spectral-core": "^1.18.3",
87+
"@stoplight/spectral-formats": "^1.6.0",
88+
"@stoplight/spectral-rulesets": "^1.18.1",
89+
"@stoplight/spectral-ruleset-bundler": "1.5.2",
9090
"@develohpanda/fluent-builder": "^2.1.2",
9191
"@fortawesome/fontawesome-svg-core": "^6.5.2",
9292
"@fortawesome/free-brands-svg-icons": "^6.5.2",

packages/insomnia/src/main/ipc/electron.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export type HandleChannels =
2222
| 'restoreBackup'
2323
| 'showOpenDialog'
2424
| 'showSaveDialog'
25-
| 'spectralRun'
2625
| 'webSocket.event.findMany'
2726
| 'webSocket.event.send'
2827
| 'webSocket.open'

packages/insomnia/src/main/ipc/main.ts

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import type { ISpectralDiagnostic } from '@stoplight/spectral-core';
2-
import type { RulesetDefinition } from '@stoplight/spectral-core';
3-
import { Spectral } from '@stoplight/spectral-core';
4-
// @ts-expect-error - This is a bundled file not sure why it's not found
5-
import { bundleAndLoadRuleset } from '@stoplight/spectral-ruleset-bundler/with-loader';
6-
import { oas } from '@stoplight/spectral-rulesets';
7-
import { app, BrowserWindow, IpcRendererEvent, net, shell } from 'electron';
1+
import { app, BrowserWindow, IpcRendererEvent, shell } from 'electron';
82
import fs from 'fs';
93

104
import type { HiddenBrowserWindowBridgeAPI } from '../../hidden-window';
@@ -28,7 +22,6 @@ export interface RendererToMainBridgeAPI {
2822
manualUpdateCheck: () => void;
2923
backup: () => Promise<void>;
3024
restoreBackup: (version: string) => Promise<void>;
31-
spectralRun: (options: { contents: string; rulesetPath: string }) => Promise<ISpectralDiagnostic[]>;
3225
authorizeUserInWindow: typeof authorizeUserInWindow;
3326
setMenuBarVisibility: (visible: boolean) => void;
3427
installPlugin: typeof installPlugin;
@@ -109,31 +102,4 @@ export function registerMainHandlers() {
109102
shell.openExternal(href);
110103
}
111104
});
112-
113-
ipcMainHandle('spectralRun', async (_, { contents, rulesetPath }: {
114-
contents: string;
115-
rulesetPath?: string;
116-
}) => {
117-
const spectral = new Spectral();
118-
119-
if (rulesetPath) {
120-
try {
121-
const ruleset = await bundleAndLoadRuleset(rulesetPath, {
122-
fs,
123-
fetch: net.fetch,
124-
});
125-
126-
spectral.setRuleset(ruleset);
127-
} catch (err) {
128-
console.log('Error while parsing ruleset:', err);
129-
spectral.setRuleset(oas as RulesetDefinition);
130-
}
131-
} else {
132-
spectral.setRuleset(oas as RulesetDefinition);
133-
}
134-
135-
const diagnostics = await spectral.run(contents);
136-
137-
return diagnostics;
138-
});
139105
}

packages/insomnia/src/main/window-utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export function createWindow(): ElectronBrowserWindow {
204204
preload: path.join(__dirname, 'preload.js'),
205205
zoomFactor: getZoomFactor(),
206206
nodeIntegration: true,
207+
nodeIntegrationInWorker: true,
207208
webviewTag: true,
208209
// TODO: enable context isolation
209210
contextIsolation: false,

packages/insomnia/src/preload.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ const main: Window['main'] = {
5050
backup: () => ipcRenderer.invoke('backup'),
5151
restoreBackup: options => ipcRenderer.invoke('restoreBackup', options),
5252
authorizeUserInWindow: options => ipcRenderer.invoke('authorizeUserInWindow', options),
53-
spectralRun: options => ipcRenderer.invoke('spectralRun', options),
5453
setMenuBarVisibility: options => ipcRenderer.send('setMenuBarVisibility', options),
5554
installPlugin: options => ipcRenderer.invoke('installPlugin', options),
5655
curlRequest: options => ipcRenderer.invoke('curlRequest', options),

packages/insomnia/src/ui/components/codemirror/code-editor.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { GraphQLInfoOptions } from 'codemirror-graphql/info';
77
import { ModifiedGraphQLJumpOptions } from 'codemirror-graphql/jump';
88
import deepEqual from 'deep-equal';
99
import { JSONPath } from 'jsonpath-plus';
10-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
10+
import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
1111
import { Button, Menu, MenuItem, MenuTrigger, Popover } from 'react-aria-components';
1212
import { useMount, useUnmount } from 'react-use';
1313
import vkBeautify from 'vkbeautify';
@@ -137,8 +137,9 @@ export interface CodeEditorHandle {
137137
focusEnd: () => void;
138138
getCursor: () => CodeMirror.Position | undefined;
139139
setCursorLine: (lineNumber: number) => void;
140+
tryToSetOption: (key: keyof EditorConfiguration, value: any) => void;
140141
}
141-
export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
142+
export const CodeEditor = memo(forwardRef<CodeEditorHandle, CodeEditorProps>(({
142143
autoPrettify,
143144
className,
144145
defaultValue,
@@ -526,6 +527,7 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
526527
useEffect(() => tryToSetOption('hintOptions', hintOptions), [hintOptions]);
527528
useEffect(() => tryToSetOption('info', infoOptions), [infoOptions]);
528529
useEffect(() => tryToSetOption('jump', jumpOptions), [jumpOptions]);
530+
// This line will trigger codeMirror lint
529531
useEffect(() => tryToSetOption('lint', lintOptions), [lintOptions]);
530532
useEffect(() => tryToSetOption('mode', !handleRender ? normalizeMimeType(mode) : { name: 'nunjucks', baseMode: normalizeMimeType(mode) }), [handleRender, mode]);
531533

@@ -551,6 +553,7 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
551553
setCursorLine: (lineNumber: number) => {
552554
codeMirror.current?.setCursor(lineNumber);
553555
},
556+
tryToSetOption,
554557
}), []);
555558

556559
const showFilter = readOnly && (mode?.includes('json') || mode?.includes('xml'));
@@ -715,5 +718,5 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
715718
}
716719
</div >
717720
);
718-
});
721+
}));
719722
CodeEditor.displayName = 'CodeEditor';

packages/insomnia/src/ui/routes/actions.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { VCSInstance } from '../../sync/vcs/insomnia-sync';
2424
import { insomniaFetch } from '../../ui/insomniaFetch';
2525
import { invariant } from '../../utils/invariant';
2626
import { SegmentEvent } from '../analytics';
27+
import { SpectralRunner } from '../worker/spectral-run';
2728

2829
// Project
2930
export const createNewProjectAction: ActionFunction = async ({ request, params }) => {
@@ -733,7 +734,10 @@ export const generateCollectionFromApiSpecAction: ActionFunction = async ({
733734
`version-control/git/${workspaceMeta?.gitRepositoryId}/other/.spectral.yaml`,
734735
);
735736

736-
const results = (await window.main.spectralRun({ contents: apiSpec.contents, rulesetPath })).filter(isLintError);
737+
const spectralRunner = new SpectralRunner();
738+
739+
const results = (await spectralRunner.runDiagnostics({ contents: apiSpec.contents, rulesetPath })).filter(isLintError);
740+
spectralRunner.terminate();
737741
if (apiSpec.contents && results && results.length) {
738742
throw new Error('Error Generating Configuration');
739743
}
@@ -772,7 +776,10 @@ export const generateCollectionAndTestsAction: ActionFunction = async ({ params
772776
`version-control/git/${workspaceMeta?.gitRepositoryId}/other/.spectral.yaml`,
773777
);
774778

775-
const results = (await window.main.spectralRun({ contents: apiSpec.contents, rulesetPath })).filter(isLintError);
779+
const spectralRunner = new SpectralRunner();
780+
781+
const results = (await spectralRunner.runDiagnostics({ contents: apiSpec.contents, rulesetPath })).filter(isLintError);
782+
spectralRunner.terminate();
776783
if (apiSpec.contents && results && results.length) {
777784
throw new Error('Error Generating Configuration');
778785
}

0 commit comments

Comments
 (0)