diff --git a/extensions/mssql/config.json b/extensions/mssql/config.json index 8e5e78cd49..f360c985d8 100644 --- a/extensions/mssql/config.json +++ b/extensions/mssql/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "3.0.0-release.243", + "version": "3.0.0-release.245", "downloadFileNames": { "Windows_86": "win-x86-net6.0.zip", "Windows_64": "win-x64-net6.0.zip", diff --git a/extensions/mssql/package.json b/extensions/mssql/package.json index 405da14c68..e63547ea72 100644 --- a/extensions/mssql/package.json +++ b/extensions/mssql/package.json @@ -383,6 +383,11 @@ "type": "boolean", "description": "%mssql.ignorePlatformWarning%", "default": false + }, + "mssql.parallelMessageProcessing": { + "type": "boolean", + "description": "%mssql.parallelMessageProcessing%", + "default": false } } }, diff --git a/extensions/mssql/package.nls.json b/extensions/mssql/package.nls.json index e4b44ab6fd..8493e2ef69 100644 --- a/extensions/mssql/package.nls.json +++ b/extensions/mssql/package.nls.json @@ -186,5 +186,6 @@ "objectsListProperties.name": "Name", "title.newTable": "New Table", - "title.designTable": "Design" + "title.designTable": "Design", + "mssql.parallelMessageProcessing" : "[Experimental] Whether the requests to the SQL Tools Service should be handled in parallel. This is introduced to discover the issues there might be when handling all requests in parallel. The default value is false. Relaunch of ADS is required when the value is changed." } diff --git a/extensions/mssql/src/sqlToolsServer.ts b/extensions/mssql/src/sqlToolsServer.ts index 2f115a89d7..ad8cd0d794 100644 --- a/extensions/mssql/src/sqlToolsServer.ts +++ b/extensions/mssql/src/sqlToolsServer.ts @@ -8,7 +8,7 @@ import { ServerOptions, TransportKind } from 'vscode-languageclient'; import * as Constants from './constants'; import * as vscode from 'vscode'; import * as path from 'path'; -import { getCommonLaunchArgsAndCleanupOldLogFiles, getOrDownloadServer } from './utils'; +import { getCommonLaunchArgsAndCleanupOldLogFiles, getOrDownloadServer, getParallelMessageProcessingConfig } from './utils'; import { Telemetry, LanguageClientErrorHandler } from './telemetry'; import { SqlOpsDataClient, ClientOptions } from 'dataprotocol-client'; import { TelemetryFeature, AgentServicesFeature, SerializationFeature, AccountFeature, SqlAssessmentServicesFeature, ProfilerFeature, TableDesignerFeature, ExecutionPlanServiceFeature } from './features'; @@ -45,7 +45,7 @@ export class SqlToolsServer { const serverPath = await this.download(context); this.installDirectory = path.dirname(serverPath); const installationComplete = Date.now(); - let serverOptions = generateServerOptions(context.extensionContext.logPath, serverPath); + let serverOptions = await generateServerOptions(context.extensionContext.logPath, serverPath); let clientOptions = getClientOptions(context); this.client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions); const processStart = Date.now(); @@ -104,8 +104,12 @@ export class SqlToolsServer { } } -function generateServerOptions(logPath: string, executablePath: string): ServerOptions { +async function generateServerOptions(logPath: string, executablePath: string): Promise { const launchArgs = getCommonLaunchArgsAndCleanupOldLogFiles(logPath, 'sqltools.log', executablePath); + const enableAsyncMessageProcessing = await getParallelMessageProcessingConfig(); + if (enableAsyncMessageProcessing) { + launchArgs.push('--parallel-message-processing'); + } return { command: executablePath, args: launchArgs, transport: TransportKind.stdio }; } diff --git a/extensions/mssql/src/utils.ts b/extensions/mssql/src/utils.ts index c77727aa33..2b176231fc 100644 --- a/extensions/mssql/src/utils.ts +++ b/extensions/mssql/src/utils.ts @@ -20,6 +20,7 @@ const configLogRetentionMinutes = 'logRetentionMinutes'; const configLogFilesRemovalLimit = 'logFilesRemovalLimit'; const extensionConfigSectionName = 'mssql'; const configLogDebugInfo = 'logDebugInfo'; +const parallelMessageProcessingConfig = 'parallelMessageProcessing'; /** * @@ -92,6 +93,18 @@ export function getConfigTracingLevel(): string { } } +export async function getParallelMessageProcessingConfig(): Promise { + const config = getConfiguration(); + if (!config) { + return false; + } + const quality = await getProductQuality(); + const setting = config.inspect(parallelMessageProcessingConfig); + // For dev environment, we want to enable the feature by default unless it is set explicitely. + // Note: the quality property is not set for dev environment, we can use this to determine whether it is dev environment. + return (quality === undefined && setting.globalValue === undefined && setting.workspaceValue === undefined) ? true : config[parallelMessageProcessingConfig]; +} + export function getLogFileName(prefix: string, pid: number): string { return `${prefix}_${pid}.log`; } @@ -352,3 +365,8 @@ export async function getOrDownloadServer(config: IConfig, handleServerEvent?: ( return serverdownloader.getOrDownloadServer(); } + +async function getProductQuality(): Promise { + const content = await fs.readFile(path.join(vscode.env.appRoot, 'product.json')); + return JSON.parse(content?.toString())?.quality; +}