Skip to content

Commit 022c636

Browse files
authored
Merge pull request #4195 from github/ginsbach/WarmDatabaseUnderlay
add commands for warming the overlay-base cache
2 parents e0a17ca + 56f8652 commit 022c636

File tree

10 files changed

+324
-23
lines changed

10 files changed

+324
-23
lines changed

extensions/ql-vscode/package.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,14 @@
515515
"command": "codeQL.runQueryContextEditor",
516516
"title": "CodeQL: Run Query on Selected Database"
517517
},
518+
{
519+
"command": "codeQL.runWarmOverlayBaseCacheForQuery",
520+
"title": "CodeQL: Warm Overlay-Base Cache for Query"
521+
},
522+
{
523+
"command": "codeQL.runWarmOverlayBaseCacheForQueryContextEditor",
524+
"title": "CodeQL: Warm Overlay-Base Cache for Query"
525+
},
518526
{
519527
"command": "codeQL.debugQuery",
520528
"title": "CodeQL: Debug Query"
@@ -571,10 +579,18 @@
571579
"command": "codeQL.runQueries",
572580
"title": "CodeQL: Run Queries in Selected Files"
573581
},
582+
{
583+
"command": "codeQL.runWarmOverlayBaseCacheForQueries",
584+
"title": "CodeQL: Warm Overlay-Base Cache for Queries in Selected Files"
585+
},
574586
{
575587
"command": "codeQL.runQuerySuite",
576588
"title": "CodeQL: Run Selected Query Suite"
577589
},
590+
{
591+
"command": "codeQL.runWarmOverlayBaseCacheForQuerySuite",
592+
"title": "CodeQL: Warm Overlay-Base Cache for Query Suite"
593+
},
578594
{
579595
"command": "codeQL.quickEval",
580596
"title": "CodeQL: Quick Evaluation"
@@ -1378,11 +1394,21 @@
13781394
"group": "9_qlCommands",
13791395
"when": "resourceScheme != codeql-zip-archive"
13801396
},
1397+
{
1398+
"command": "codeQL.runWarmOverlayBaseCacheForQueries",
1399+
"group": "9_qlCommands",
1400+
"when": "resourceScheme != codeql-zip-archive && config.codeQL.canary"
1401+
},
13811402
{
13821403
"command": "codeQL.runQuerySuite",
13831404
"group": "9_qlCommands",
13841405
"when": "resourceScheme != codeql-zip-archive && resourceExtname == .qls && !explorerResourceIsFolder && !listMultiSelection && config.codeQL.canary"
13851406
},
1407+
{
1408+
"command": "codeQL.runWarmOverlayBaseCacheForQuerySuite",
1409+
"group": "9_qlCommands",
1410+
"when": "resourceScheme != codeql-zip-archive && resourceExtname == .qls && !explorerResourceIsFolder && !listMultiSelection && config.codeQL.canary"
1411+
},
13861412
{
13871413
"command": "codeQL.runVariantAnalysisContextExplorer",
13881414
"group": "9_qlCommands",
@@ -1408,6 +1434,10 @@
14081434
"command": "codeQL.runQuery",
14091435
"when": "resourceLangId == ql && resourceExtname == .ql"
14101436
},
1437+
{
1438+
"command": "codeQL.runWarmOverlayBaseCacheForQuery",
1439+
"when": "resourceLangId == ql && resourceExtname == .ql && config.codeQL.canary"
1440+
},
14111441
{
14121442
"command": "codeQLQueries.runLocalQueryFromQueriesPanel",
14131443
"when": "false"
@@ -1428,6 +1458,10 @@
14281458
"command": "codeQL.runQueryContextEditor",
14291459
"when": "false"
14301460
},
1461+
{
1462+
"command": "codeQL.runWarmOverlayBaseCacheForQueryContextEditor",
1463+
"when": "false"
1464+
},
14311465
{
14321466
"command": "codeQL.debugQuery",
14331467
"when": "config.codeQL.canary && editorLangId == ql && resourceExtname == .ql && !inDebugMode"
@@ -1480,10 +1514,18 @@
14801514
"command": "codeQL.runQueries",
14811515
"when": "false"
14821516
},
1517+
{
1518+
"command": "codeQL.runWarmOverlayBaseCacheForQueries",
1519+
"when": "false"
1520+
},
14831521
{
14841522
"command": "codeQL.runQuerySuite",
14851523
"when": "false"
14861524
},
1525+
{
1526+
"command": "codeQL.runWarmOverlayBaseCacheForQuerySuite",
1527+
"when": "false"
1528+
},
14871529
{
14881530
"command": "codeQL.quickEval",
14891531
"when": "editorLangId == ql"
@@ -1832,6 +1874,10 @@
18321874
"command": "codeQL.runQueryContextEditor",
18331875
"when": "editorLangId == ql && resourceExtname == .ql && !inDebugMode"
18341876
},
1877+
{
1878+
"command": "codeQL.runWarmOverlayBaseCacheForQueryContextEditor",
1879+
"when": "editorLangId == ql && resourceExtname == .ql && !inDebugMode && config.codeQL.canary"
1880+
},
18351881
{
18361882
"command": "codeQL.runQueryOnMultipleDatabasesContextEditor",
18371883
"when": "editorLangId == ql && resourceExtname == .ql"

extensions/ql-vscode/src/common/commands.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,11 @@ export type QueryEditorCommands = {
126126
// Commands used for running local queries
127127
export type LocalQueryCommands = {
128128
"codeQL.runQuery": (uri?: Uri) => Promise<void>;
129+
"codeQL.runWarmOverlayBaseCacheForQuery": (uri?: Uri) => Promise<void>;
129130
"codeQL.runQueryContextEditor": (uri?: Uri) => Promise<void>;
131+
"codeQL.runWarmOverlayBaseCacheForQueryContextEditor": (
132+
uri?: Uri,
133+
) => Promise<void>;
130134
"codeQL.runQueryOnMultipleDatabases": (uri?: Uri) => Promise<void>;
131135
"codeQL.runQueryOnMultipleDatabasesContextEditor": (
132136
uri?: Uri,
@@ -138,7 +142,9 @@ export type LocalQueryCommands = {
138142
"codeQLQueries.createQuery": () => Promise<void>;
139143
"codeQL.runLocalQueryFromFileTab": (uri: Uri) => Promise<void>;
140144
"codeQL.runQueries": ExplorerSelectionCommandFunction<Uri>;
145+
"codeQL.runWarmOverlayBaseCacheForQueries": ExplorerSelectionCommandFunction<Uri>;
141146
"codeQL.runQuerySuite": ExplorerSelectionCommandFunction<Uri>;
147+
"codeQL.runWarmOverlayBaseCacheForQuerySuite": ExplorerSelectionCommandFunction<Uri>;
142148
"codeQL.quickEval": (uri: Uri) => Promise<void>;
143149
"codeQL.quickEvalCount": (uri: Uri) => Promise<void>;
144150
"codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>;

extensions/ql-vscode/src/common/logging/vscode/loggers.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ export const extLogger = new OutputChannelLogger("CodeQL Extension Log");
1010
// Logger for messages from the query server.
1111
export const queryServerLogger = new OutputChannelLogger("CodeQL Query Server");
1212

13+
// Logger for messages from the query server for warming overlay-base cache.
14+
let queryServerForWarmingOverlayBaseCacheLogger:
15+
| OutputChannelLogger
16+
| undefined;
17+
18+
// construct queryServerForWarmingOverlayBaseCacheLogger lazily, as most users don't need it
19+
export function getQueryServerForWarmingOverlayBaseCacheLogger(): OutputChannelLogger {
20+
if (!queryServerForWarmingOverlayBaseCacheLogger)
21+
queryServerForWarmingOverlayBaseCacheLogger = new OutputChannelLogger(
22+
"CodeQL Query Server for warming overlay-base cache",
23+
);
24+
return queryServerForWarmingOverlayBaseCacheLogger;
25+
}
26+
1327
// Logger for messages from the language server.
1428
export const languageServerLogger = new OutputChannelLogger(
1529
"CodeQL Language Server",

extensions/ql-vscode/src/databases/local-databases/database-manager.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,35 @@ export class DatabaseManager extends DisposableObject {
739739
}
740740
}
741741

742+
public async runWithDatabaseInSeparateQueryRunner(
743+
queryRunner: QueryRunner,
744+
whatToDo: () => Promise<void>,
745+
) {
746+
try {
747+
if (this._currentDatabaseItem) {
748+
const dbItem = this._currentDatabaseItem;
749+
await this.qs.deregisterDatabase(dbItem);
750+
await queryRunner.registerDatabase(dbItem);
751+
}
752+
await whatToDo();
753+
if (this._currentDatabaseItem) {
754+
const dbItem = this._currentDatabaseItem;
755+
await queryRunner.deregisterDatabase(dbItem);
756+
await this.qs.registerDatabase(dbItem);
757+
}
758+
} catch (e) {
759+
const message = getErrorMessage(e);
760+
if (message === "Connection is disposed.") {
761+
// This is expected if the query server is not running.
762+
void extLogger.log(
763+
`Could not use database for warming overlay-base cache because query server is not running.`,
764+
);
765+
return;
766+
}
767+
throw e;
768+
}
769+
}
770+
742771
private async deregisterDatabase(dbItem: DatabaseItem) {
743772
try {
744773
await this.qs.deregisterDatabase(dbItem);

extensions/ql-vscode/src/extension.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ import {
8686
extLogger,
8787
languageServerLogger,
8888
queryServerLogger,
89+
getQueryServerForWarmingOverlayBaseCacheLogger,
8990
} from "./common/logging/vscode";
9091
import { QueryHistoryManager } from "./query-history/query-history-manager";
9192
import type { CompletedLocalQueryInfo } from "./query-results";
@@ -172,6 +173,7 @@ function getCommands(
172173
app: App,
173174
cliServer: CodeQLCliServer,
174175
queryRunner: QueryRunner,
176+
queryRunnerForWarmingOverlayBaseCache: QueryRunner | undefined,
175177
languageClient: LanguageClient,
176178
): BaseCommands {
177179
const getCliVersion = async () => {
@@ -189,6 +191,9 @@ function getCommands(
189191
cliServer.restartCliServer();
190192
await Promise.all([
191193
queryRunner.restartQueryServer(progress),
194+
queryRunnerForWarmingOverlayBaseCache
195+
? queryRunnerForWarmingOverlayBaseCache.restartQueryServer(progress)
196+
: {},
192197
async () => {
193198
if (languageClient.isRunning()) {
194199
await languageClient.restart();
@@ -201,6 +206,12 @@ function getCommands(
201206
queryServerLogger,
202207
"CodeQL Query Server restarted.",
203208
);
209+
if (queryRunnerForWarmingOverlayBaseCache) {
210+
void showAndLogErrorMessage(
211+
getQueryServerForWarmingOverlayBaseCacheLogger(),
212+
"CodeQL Query Server for warming overlay-base cache restarted.",
213+
);
214+
}
204215
},
205216
{
206217
title: "Restarting Query Server",
@@ -281,6 +292,7 @@ export interface CodeQLExtensionInterface {
281292
readonly ctx: ExtensionContext;
282293
readonly cliServer: CodeQLCliServer;
283294
readonly qs: QueryRunner;
295+
readonly qsForWarmingOverlayBaseCache: QueryRunner | undefined;
284296
readonly distributionManager: DistributionManager;
285297
readonly databaseManager: DatabaseManager;
286298
readonly databaseUI: DatabaseUI;
@@ -795,8 +807,28 @@ async function activateWithInstalledDistribution(
795807
qlConfigurationListener,
796808
cliServer,
797809
ctx,
810+
false,
798811
);
799812

813+
let qsForWarmingOverlayBaseCache: QueryRunner | undefined;
814+
815+
// construct qsForWarmingOverlayBaseCache lazily, as most users don't need it
816+
async function getQsForWarmingOverlayBaseCache(): Promise<QueryRunner> {
817+
if (!qsForWarmingOverlayBaseCache) {
818+
void extLogger.log(
819+
"Initializing base cache warming query server client.",
820+
);
821+
qsForWarmingOverlayBaseCache = await createQueryServer(
822+
app,
823+
qlConfigurationListener,
824+
cliServer,
825+
ctx,
826+
true,
827+
);
828+
}
829+
return qsForWarmingOverlayBaseCache;
830+
}
831+
800832
for (const glob of CLEAR_PACK_CACHE_ON_EDIT_GLOBS) {
801833
const fsWatcher = workspace.createFileSystemWatcher(glob);
802834
ctx.subscriptions.push(fsWatcher);
@@ -998,6 +1030,7 @@ async function activateWithInstalledDistribution(
9981030
const localQueries = new LocalQueries(
9991031
app,
10001032
qs,
1033+
getQsForWarmingOverlayBaseCache,
10011034
qhm,
10021035
dbm,
10031036
databaseFetcher,
@@ -1062,7 +1095,13 @@ async function activateWithInstalledDistribution(
10621095
void extLogger.log("Registering top-level command palette commands.");
10631096

10641097
const allCommands: AllExtensionCommands = {
1065-
...getCommands(app, cliServer, qs, languageClient),
1098+
...getCommands(
1099+
app,
1100+
cliServer,
1101+
qs,
1102+
qsForWarmingOverlayBaseCache,
1103+
languageClient,
1104+
),
10661105
...getQueryEditorCommands({
10671106
commandManager: app.commands,
10681107
queryRunner: qs,
@@ -1165,6 +1204,7 @@ async function activateWithInstalledDistribution(
11651204
cliServer,
11661205
localQueries,
11671206
qs,
1207+
qsForWarmingOverlayBaseCache,
11681208
distributionManager,
11691209
databaseManager: dbm,
11701210
databaseUI,
@@ -1278,9 +1318,12 @@ async function createQueryServer(
12781318
qlConfigurationListener: QueryServerConfigListener,
12791319
cliServer: CodeQLCliServer,
12801320
ctx: ExtensionContext,
1321+
warmOverlayBaseCache: boolean,
12811322
): Promise<QueryRunner> {
12821323
const qsOpts = {
1283-
logger: queryServerLogger,
1324+
logger: warmOverlayBaseCache
1325+
? getQueryServerForWarmingOverlayBaseCacheLogger()
1326+
: queryServerLogger,
12841327
contextStoragePath: getContextStoragePath(ctx),
12851328
};
12861329
const progressCallback = (
@@ -1290,7 +1333,12 @@ async function createQueryServer(
12901333
) => Thenable<void>,
12911334
) =>
12921335
Window.withProgress(
1293-
{ title: "CodeQL query server", location: ProgressLocation.Window },
1336+
{
1337+
title: warmOverlayBaseCache
1338+
? "CodeQL query server for warming overlay-base cache"
1339+
: "CodeQL query server",
1340+
location: ProgressLocation.Window,
1341+
},
12941342
task,
12951343
);
12961344

@@ -1300,6 +1348,7 @@ async function createQueryServer(
13001348
cliServer,
13011349
qsOpts,
13021350
progressCallback,
1351+
warmOverlayBaseCache,
13031352
);
13041353
ctx.subscriptions.push(qs);
13051354
await qs.startQueryServer();

extensions/ql-vscode/src/language-support/ast-viewer/ast-cfg-commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export function getAstCfgCommands({
5959
progress,
6060
token,
6161
undefined,
62+
false,
6263
undefined,
6364
res[1],
6465
);

0 commit comments

Comments
 (0)