Skip to content

Commit af7e39d

Browse files
committed
introduce compiledScriptCache
1 parent 0ba410f commit af7e39d

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import crypto from 'crypto';
12
import vm from 'vm';
23
import fs from 'fs';
34
import path from 'path';
@@ -47,6 +48,7 @@ export class DataSchemaCompiler {
4748
this.pythonContext = null;
4849
this.workerPool = null;
4950
this.compilerId = options.compilerId;
51+
this.compiledScriptCache = options.compiledScriptCache;
5052
}
5153

5254
compileObjects(compileServices, objects, errorsReport) {
@@ -370,6 +372,18 @@ export class DataSchemaCompiler {
370372
}
371373
}
372374

375+
getJsScript(file) {
376+
const cacheKey = crypto.createHash('md5').update(JSON.stringify(file.content)).digest('hex');
377+
378+
if (this.compiledScriptCache.has(cacheKey)) {
379+
return this.compiledScriptCache.get(cacheKey);
380+
}
381+
382+
const script = new vm.Script(file.content, { filename: file.fileName, timeout: 15000 });
383+
this.compiledScriptCache.set(cacheKey, script);
384+
return script;
385+
}
386+
373387
compileJsFile(file, errorsReport, cubes, contexts, exports, asyncModules, toCompile, compiledFiles, { doSyntaxCheck } = { doSyntaxCheck: false }) {
374388
if (doSyntaxCheck) {
375389
// There is no need to run syntax check for data model files
@@ -382,7 +396,9 @@ export class DataSchemaCompiler {
382396
}
383397

384398
try {
385-
vm.runInNewContext(file.content, {
399+
const script = this.getJsScript(file);
400+
401+
script.runInNewContext({
386402
view: (name, cube) => (
387403
!cube ?
388404
this.cubeFactory({ ...name, fileName: file.fileName, isView: true }) :

packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { SchemaFileRepository } from '@cubejs-backend/shared';
22
import { NativeInstance } from '@cubejs-backend/native';
33
import { v4 as uuidv4 } from 'uuid';
4+
import { LRUCache } from 'lru-cache';
5+
import vm from 'vm';
46

57
import { CubeValidator } from './CubeValidator';
68
import { DataSchemaCompiler } from './DataSchemaCompiler';
@@ -32,6 +34,7 @@ export type PrepareCompilerOptions = {
3234
standalone?: boolean;
3335
headCommitId?: string;
3436
adapter?: string;
37+
compiledScriptCache?: LRUCache<string, vm.Script>;
3538
};
3639

3740
export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareCompilerOptions = {}) => {
@@ -49,6 +52,8 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
4952
const compilerCache = new CompilerCache({ maxQueryCacheSize, maxQueryCacheAge });
5053
const yamlCompiler = new YamlCompiler(cubeSymbols, cubeDictionary, nativeInstance, viewCompiler);
5154

55+
const compiledScriptCache = options.compiledScriptCache || new LRUCache<string, vm.Script>({ max: 250 });
56+
5257
const transpilers: TranspilerInterface[] = [
5358
new ValidationTranspiler(),
5459
new ImportExportTranspiler(),
@@ -66,6 +71,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
6671
preTranspileCubeCompilers: [cubeSymbols, cubeValidator],
6772
transpilers,
6873
viewCompilationGate,
74+
compiledScriptCache,
6975
viewCompilers: [viewCompiler],
7076
cubeCompilers: [cubeEvaluator, joinGraph, metaTransformer],
7177
contextCompilers: [contextEvaluator],

packages/cubejs-server-core/src/core/CompilerApi.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import crypto from 'crypto';
22
import R from 'ramda';
33
import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler';
4-
import { v4 as uuidv4, parse as uuidParse, stringify as uuidStringify } from 'uuid';
4+
import { v4 as uuidv4, parse as uuidParse } from 'uuid';
5+
import { LRUCache } from 'lru-cache';
56
import { NativeInstance } from '@cubejs-backend/native';
67

78
export class CompilerApi {
@@ -29,6 +30,11 @@ export class CompilerApi {
2930
this.sqlCache = options.sqlCache;
3031
this.standalone = options.standalone;
3132
this.nativeInstance = this.createNativeInstance();
33+
this.compiledScriptCache = new LRUCache({
34+
max: options.compilerCacheSize || 250,
35+
ttl: options.maxCompilerCacheKeepAlive,
36+
updateAgeOnGet: options.updateCompilerCacheKeepAlive
37+
});
3238
}
3339

3440
setGraphQLSchema(schema) {
@@ -83,6 +89,7 @@ export class CompilerApi {
8389
allowJsDuplicatePropsInSchema: this.allowJsDuplicatePropsInSchema,
8490
standalone: this.standalone,
8591
nativeInstance: this.nativeInstance,
92+
compiledScriptCache: this.compiledScriptCache,
8693
});
8794
this.queryFactory = await this.createQueryFactory(compilers);
8895

packages/cubejs-server-core/src/core/server.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,9 @@ export class CubejsServerCore {
714714
standalone: this.standalone,
715715
allowNodeRequire: options.allowNodeRequire,
716716
fastReload: options.fastReload || getEnv('fastReload'),
717+
compilerCacheSize: this.options.compilerCacheSize || 250,
718+
maxCompilerCacheKeepAlive: this.options.maxCompilerCacheKeepAlive,
719+
updateCompilerCacheKeepAlive: this.options.updateCompilerCacheKeepAlive
717720
},
718721
);
719722
}

0 commit comments

Comments
 (0)