Skip to content

Commit 7ef6282

Browse files
authored
feat(server-core): Introduce CUBEJS_REFRESH_WORKER_CONCURRENCY env and update default concurrency settings for drivers (#9168)
* add CUBEJS_SCHEDULED_REFRESH_QUERIES_PER_APP_ID and deprecate CUBEJS_SCHEDULED_REFRESH_CONCURRENCY * increase DefaultConcurrency settings for drivers * use refreshWorkerConcurrency only for refresh workers * correct warn flow for refreshConcurrency * correct queueOptionsWrapper flow * fix unit tests * add tests for CUBEJS_REFRESH_WORKER_CONCURRENCY
1 parent ae5d977 commit 7ef6282

File tree

10 files changed

+89
-19
lines changed

10 files changed

+89
-19
lines changed

packages/cubejs-athena-driver/src/AthenaDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class AthenaDriver extends BaseDriver implements DriverInterface {
7676
* Returns default concurrency value.
7777
*/
7878
public static getDefaultConcurrency(): number {
79-
return 5;
79+
return 10;
8080
}
8181

8282
private config: AthenaDriverOptionsInitialized;

packages/cubejs-backend-shared/src/env.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,33 @@ const variables: Record<string, (...args: any) => any> = {
170170
// It's true by default for development
171171
return process.env.NODE_ENV !== 'production';
172172
},
173+
scheduledRefreshQueriesPerAppId: () => {
174+
const refreshQueries = get('CUBEJS_SCHEDULED_REFRESH_QUERIES_PER_APP_ID').asIntPositive();
175+
176+
if (refreshQueries) {
177+
return refreshQueries;
178+
}
179+
180+
const refreshConcurrency = get('CUBEJS_SCHEDULED_REFRESH_CONCURRENCY').asIntPositive();
181+
182+
if (refreshConcurrency) {
183+
console.warn(
184+
'The CUBEJS_SCHEDULED_REFRESH_CONCURRENCY is deprecated. Please, use the CUBEJS_SCHEDULED_REFRESH_QUERIES_PER_APP_ID instead.'
185+
);
186+
}
187+
188+
return refreshConcurrency;
189+
},
190+
refreshWorkerConcurrency: () => get('CUBEJS_REFRESH_WORKER_CONCURRENCY')
191+
.asIntPositive(),
192+
// eslint-disable-next-line consistent-return
193+
scheduledRefreshTimezones: () => {
194+
const timezones = get('CUBEJS_SCHEDULED_REFRESH_TIMEZONES').asString();
195+
196+
if (timezones) {
197+
return timezones.split(',').map(t => t.trim());
198+
}
199+
},
173200
preAggregationsBuilder: () => get('CUBEJS_PRE_AGGREGATIONS_BUILDER').asBool(),
174201
gracefulShutdown: () => get('CUBEJS_GRACEFUL_SHUTDOWN')
175202
.asIntPositive(),

packages/cubejs-clickhouse-driver/src/ClickHouseDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class ClickHouseDriver extends BaseDriver implements DriverInterface {
119119
* Returns default concurrency value.
120120
*/
121121
public static getDefaultConcurrency(): number {
122-
return 5;
122+
return 10;
123123
}
124124

125125
// ClickHouseClient has internal pool of several sockets, no need for generic-pool

packages/cubejs-databricks-jdbc-driver/src/DatabricksDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export class DatabricksDriver extends JDBCDriver {
147147
* Returns default concurrency value.
148148
*/
149149
public static getDefaultConcurrency(): number {
150-
return 2;
150+
return 10;
151151
}
152152

153153
/**

packages/cubejs-firebolt-driver/src/FireboltDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class FireboltDriver extends BaseDriver implements DriverInterface {
4646
* Returns default concurrency value.
4747
*/
4848
public static getDefaultConcurrency(): number {
49-
return 5;
49+
return 10;
5050
}
5151

5252
private config: FireboltDriverConfiguration;

packages/cubejs-pinot-driver/src/PinotDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class PinotDriver extends BaseDriver implements DriverInterface {
7474
* Returns default concurrency value.
7575
*/
7676
public static getDefaultConcurrency() {
77-
return 2;
77+
return 10;
7878
}
7979

8080
private config: PinotDriverConfiguration;

packages/cubejs-redshift-driver/src/RedshiftDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class RedshiftDriver extends PostgresDriver<RedshiftDriverConfiguration>
5757
* Returns default concurrency value.
5858
*/
5959
public static getDefaultConcurrency(): number {
60-
return 4;
60+
return 5;
6161
}
6262

6363
/**

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ export class OptsHandler {
287287
private queueOptionsWrapper(
288288
context: RequestContext,
289289
queueOptions: unknown | ((dataSource?: string) => QueueOptions),
290+
queueType: 'query' | 'pre-aggs',
290291
): (dataSource?: string) => Promise<QueueOptions> {
291292
return async (dataSource = 'default') => {
292293
const options = (
@@ -298,6 +299,14 @@ export class OptsHandler {
298299
// concurrency specified in cube.js
299300
return options;
300301
} else {
302+
const workerConcurrency = getEnv('refreshWorkerConcurrency');
303+
if (queueType === 'pre-aggs' && workerConcurrency) {
304+
return {
305+
...options,
306+
concurrency: workerConcurrency,
307+
};
308+
}
309+
301310
const envConcurrency: number = getEnv('concurrency', { dataSource });
302311
if (envConcurrency) {
303312
// concurrency specified in CUBEJS_CONCURRENCY
@@ -320,7 +329,7 @@ export class OptsHandler {
320329
// no specified concurrency
321330
return {
322331
...options,
323-
concurrency: 2,
332+
concurrency: 5,
324333
};
325334
}
326335
}
@@ -453,15 +462,12 @@ export class OptsHandler {
453462
externalDialectFactory,
454463
apiSecret: process.env.CUBEJS_API_SECRET,
455464
telemetry: getEnv('telemetry'),
456-
scheduledRefreshTimeZones:
457-
process.env.CUBEJS_SCHEDULED_REFRESH_TIMEZONES &&
458-
process.env.CUBEJS_SCHEDULED_REFRESH_TIMEZONES.split(',').map(t => t.trim()),
465+
scheduledRefreshTimeZones: getEnv('scheduledRefreshTimezones'),
459466
scheduledRefreshContexts: async () => [null],
460467
basePath: '/cubejs-api',
461468
dashboardAppPath: 'dashboard-app',
462469
dashboardAppPort: 3000,
463-
scheduledRefreshConcurrency:
464-
parseInt(process.env.CUBEJS_SCHEDULED_REFRESH_CONCURRENCY, 10),
470+
scheduledRefreshConcurrency: getEnv('scheduledRefreshQueriesPerAppId'),
465471
scheduledRefreshBatchSize: getEnv('scheduledRefreshBatchSize'),
466472
preAggregationsSchema:
467473
getEnv('preAggregationsSchema') ||
@@ -662,13 +668,15 @@ export class OptsHandler {
662668
clone.queryCacheOptions.queueOptions = this.queueOptionsWrapper(
663669
context,
664670
clone.queryCacheOptions.queueOptions,
671+
'query'
665672
);
666673

667674
// pre-aggs queue options
668675
clone.preAggregationsOptions = clone.preAggregationsOptions || {};
669676
clone.preAggregationsOptions.queueOptions = this.queueOptionsWrapper(
670677
context,
671678
clone.preAggregationsOptions.queueOptions,
679+
'pre-aggs'
672680
);
673681

674682
// pre-aggs external refresh flag (force to run pre-aggs build flow first if

packages/cubejs-server-core/test/unit/OptsHandler.test.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,13 +525,13 @@ describe('OptsHandler class', () => {
525525
expect(opts.queryCacheOptions.queueOptions).toBeDefined();
526526
expect(typeof opts.queryCacheOptions.queueOptions).toEqual('function');
527527
expect(await opts.queryCacheOptions.queueOptions()).toEqual({
528-
concurrency: 2,
528+
concurrency: 5,
529529
});
530530

531531
expect(opts.preAggregationsOptions.queueOptions).toBeDefined();
532532
expect(typeof opts.preAggregationsOptions.queueOptions).toEqual('function');
533533
expect(await opts.preAggregationsOptions.queueOptions()).toEqual({
534-
concurrency: 2,
534+
concurrency: 5,
535535
});
536536
}
537537
);
@@ -555,13 +555,13 @@ describe('OptsHandler class', () => {
555555
expect(opts.queryCacheOptions.queueOptions).toBeDefined();
556556
expect(typeof opts.queryCacheOptions.queueOptions).toEqual('function');
557557
expect(await opts.queryCacheOptions.queueOptions()).toEqual({
558-
concurrency: 2,
558+
concurrency: 5,
559559
});
560560

561561
expect(opts.preAggregationsOptions.queueOptions).toBeDefined();
562562
expect(typeof opts.preAggregationsOptions.queueOptions).toEqual('function');
563563
expect(await opts.preAggregationsOptions.queueOptions()).toEqual({
564-
concurrency: 2,
564+
concurrency: 5,
565565
});
566566
}
567567
);
@@ -585,13 +585,13 @@ describe('OptsHandler class', () => {
585585
expect(opts.queryCacheOptions.queueOptions).toBeDefined();
586586
expect(typeof opts.queryCacheOptions.queueOptions).toEqual('function');
587587
expect(await opts.queryCacheOptions.queueOptions()).toEqual({
588-
concurrency: 2,
588+
concurrency: 5,
589589
});
590590

591591
expect(opts.preAggregationsOptions.queueOptions).toBeDefined();
592592
expect(typeof opts.preAggregationsOptions.queueOptions).toEqual('function');
593593
expect(await opts.preAggregationsOptions.queueOptions()).toEqual({
594-
concurrency: 2,
594+
concurrency: 5,
595595
});
596596
}
597597
);
@@ -658,6 +658,41 @@ describe('OptsHandler class', () => {
658658
}
659659
);
660660

661+
test(
662+
'must configure queueOptions with empty orchestratorOptions function, ' +
663+
'with CUBEJS_REFRESH_WORKER_CONCURRENCY, CUBEJS_CONCURRENCY and with default driver concurrency',
664+
async () => {
665+
process.env.CUBEJS_CONCURRENCY = '11';
666+
process.env.CUBEJS_REFRESH_WORKER_CONCURRENCY = '22';
667+
process.env.CUBEJS_DB_TYPE = 'postgres';
668+
669+
const core = new CubejsServerCoreExposed({
670+
...conf,
671+
dbType: undefined,
672+
driverFactory: () => ({ type: <DatabaseType>process.env.CUBEJS_DB_TYPE }),
673+
orchestratorOptions: () => ({}),
674+
});
675+
676+
const opts = (<any> await core.getOrchestratorApi(<RequestContext>{})).options;
677+
678+
expect(opts.queryCacheOptions.queueOptions).toBeDefined();
679+
expect(typeof opts.queryCacheOptions.queueOptions).toEqual('function');
680+
expect(await opts.queryCacheOptions.queueOptions()).toEqual({
681+
concurrency: parseInt(process.env.CUBEJS_CONCURRENCY, 10),
682+
});
683+
684+
expect(opts.preAggregationsOptions.queueOptions).toBeDefined();
685+
expect(typeof opts.preAggregationsOptions.queueOptions).toEqual('function');
686+
expect(await opts.preAggregationsOptions.queueOptions()).toEqual({
687+
concurrency: parseInt(process.env.CUBEJS_REFRESH_WORKER_CONCURRENCY, 10),
688+
});
689+
690+
delete process.env.CUBEJS_CONCURRENCY;
691+
delete process.env.CUBEJS_REFRESH_WORKER_CONCURRENCY;
692+
delete process.env.CUBEJS_DB_TYPE;
693+
}
694+
);
695+
661696
test(
662697
'multi data source concurrency',
663698
async () => {

packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
195195
* Returns default concurrency value.
196196
*/
197197
public static getDefaultConcurrency(): number {
198-
return 5;
198+
return 8;
199199
}
200200

201201
public static driverEnvVariables() {

0 commit comments

Comments
 (0)