diff --git a/news/2 Fixes/6729.md b/news/2 Fixes/6729.md new file mode 100644 index 000000000000..65c2e4ff2706 --- /dev/null +++ b/news/2 Fixes/6729.md @@ -0,0 +1 @@ +Make the dataviewer open a window much faster. Total load time is the same, but initial response is much faster. diff --git a/package-lock.json b/package-lock.json index 58aeb6bcbc8d..9fe4953b8dcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4207,8 +4207,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4232,15 +4231,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4257,22 +4254,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -4403,8 +4397,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -4418,7 +4411,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4435,7 +4427,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4444,15 +4435,13 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4473,7 +4462,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -4562,8 +4550,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -4577,7 +4564,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4673,8 +4659,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -4716,7 +4701,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4738,7 +4722,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4787,15 +4770,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, @@ -8385,8 +8366,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -8410,15 +8390,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8433,22 +8411,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -8579,8 +8554,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -8594,7 +8568,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -8611,7 +8584,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -8620,8 +8592,7 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", @@ -8645,7 +8616,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -8734,8 +8704,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -8749,7 +8718,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -8886,7 +8854,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -8908,7 +8875,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8948,7 +8914,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -8968,8 +8933,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true + "dev": true } } }, @@ -8994,8 +8958,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", @@ -12343,9 +12306,9 @@ } }, "lodash": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash._reinterpolate": { "version": "3.0.0", diff --git a/package.json b/package.json index 8f440e56599c..5eec0b5a1100 100644 --- a/package.json +++ b/package.json @@ -2358,7 +2358,7 @@ "@jupyterlab/services": "^3.2.1", "ansi-regex": "^4.1.0", "arch": "^2.1.0", - "azure-storage": "^2.10.1", + "azure-storage": "^2.10.3", "diff-match-patch": "^1.0.0", "fs-extra": "^4.0.3", "fuzzy": "^0.1.3", @@ -2370,7 +2370,7 @@ "jsonc-parser": "^2.0.3", "less-plugin-inline-urls": "^1.2.0", "line-by-line": "^0.1.6", - "lodash": "^4.17.13", + "lodash": "^4.17.15", "md5": "^2.2.1", "minimatch": "^3.0.4", "monaco-editor-textmate": "^2.1.1", diff --git a/src/client/datascience/data-viewing/dataViewerProvider.ts b/src/client/datascience/data-viewing/dataViewerProvider.ts index 0989e79fd8cf..a56cc1ee7598 100644 --- a/src/client/datascience/data-viewing/dataViewerProvider.ts +++ b/src/client/datascience/data-viewing/dataViewerProvider.ts @@ -11,6 +11,8 @@ import * as localize from '../../common/utils/localize'; import { noop } from '../../common/utils/misc'; import { IInterpreterService } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; +import { sendTelemetryEvent } from '../../telemetry'; +import { Telemetry } from '../constants'; import { IDataViewer, IDataViewerProvider, IJupyterVariables } from '../types'; @injectable() @@ -32,20 +34,35 @@ export class DataViewerProvider implements IDataViewerProvider, IAsyncDisposable } public async create(variable: string): Promise { - // Make sure this is a valid variable - const variables = await this.variables.getVariables(); - const index = variables.findIndex(v => v && v.name === variable); - if (index >= 0) { - const dataExplorer = this.serviceContainer.get(IDataViewer); - this.activeExplorers.push(dataExplorer); - await dataExplorer.showVariable(variables[index]); - return dataExplorer; - } + let result: IDataViewer | undefined; + + // Create the data explorer (this should show the window) + const dataExplorer = this.serviceContainer.get(IDataViewer); + try { + // Verify this is allowed. + await this.checkPandas(); - throw new Error(localize.DataScience.dataExplorerInvalidVariableFormat().format(variable)); + // Make sure this is a valid variable + const variables = await this.variables.getVariables(); + const index = variables.findIndex(v => v && v.name === variable); + if (index >= 0) { + // Then load the data. + this.activeExplorers.push(dataExplorer); + await dataExplorer.showVariable(variables[index]); + result = dataExplorer; + } else { + throw new Error(localize.DataScience.dataExplorerInvalidVariableFormat().format(variable)); + } + } finally { + if (!result) { + // If throw any errors, close the window we opened. + dataExplorer.dispose(); + } + } + return result; } - public async getPandasVersion(): Promise<{ major: number; minor: number; build: number } | undefined> { + private async getPandasVersion(): Promise<{ major: number; minor: number; build: number } | undefined> { const interpreter = await this.interpreterService.getActiveInterpreter(); const launcher = await this.pythonFactory.createActivatedEnvironment({ resource: undefined, interpreter, allowEnvironmentFetchExceptions: true }); try { @@ -61,4 +78,18 @@ export class DataViewerProvider implements IDataViewerProvider, IAsyncDisposable noop(); } } + + private async checkPandas(): Promise { + const pandasVersion = await this.getPandasVersion(); + if (!pandasVersion) { + sendTelemetryEvent(Telemetry.PandasNotInstalled); + // Warn user that there is no pandas. + throw new Error(localize.DataScience.pandasRequiredForViewing()); + } else if (pandasVersion.major < 1 && pandasVersion.minor < 20) { + sendTelemetryEvent(Telemetry.PandasTooOld); + // Warn user that we cannot start because pandas is too old. + const versionStr = `${pandasVersion.major}.${pandasVersion.minor}.${pandasVersion.build}`; + throw new Error(localize.DataScience.pandasTooOldForViewingFormat().format(versionStr)); + } + } } diff --git a/src/client/datascience/interactive-window/interactiveWindow.ts b/src/client/datascience/interactive-window/interactiveWindow.ts index d0a93dd4392b..cdf805e07216 100644 --- a/src/client/datascience/interactive-window/interactiveWindow.ts +++ b/src/client/datascience/interactive-window/interactiveWindow.ts @@ -570,23 +570,6 @@ export class InteractiveWindow extends WebViewHost im this.addMessageImpl(message, 'preview'); } - private async checkPandas(): Promise { - const pandasVersion = await this.dataExplorerProvider.getPandasVersion(); - if (!pandasVersion) { - sendTelemetryEvent(Telemetry.PandasNotInstalled); - // Warn user that there is no pandas. - this.applicationShell.showErrorMessage(localize.DataScience.pandasRequiredForViewing()); - return false; - } else if (pandasVersion.major < 1 && pandasVersion.minor < 20) { - sendTelemetryEvent(Telemetry.PandasTooOld); - // Warn user that we cannot start because pandas is too old. - const versionStr = `${pandasVersion.major}.${pandasVersion.minor}.${pandasVersion.build}`; - this.applicationShell.showErrorMessage(localize.DataScience.pandasTooOldForViewingFormat().format(versionStr)); - return false; - } - return true; - } - private shouldAskForLargeData(): boolean { const settings = this.configuration.getSettings(); return settings && settings.datascience && settings.datascience.askForLargeDataFrames === true; @@ -618,7 +601,7 @@ export class InteractiveWindow extends WebViewHost im private async showDataViewer(request: IShowDataViewer): Promise { try { - if (await this.checkPandas() && await this.checkColumnSize(request.columnSize)) { + if (await this.checkColumnSize(request.columnSize)) { await this.dataExplorerProvider.create(request.variableName); } } catch (e) { diff --git a/src/client/datascience/types.ts b/src/client/datascience/types.ts index 98658dd0c412..451e103a29c2 100644 --- a/src/client/datascience/types.ts +++ b/src/client/datascience/types.ts @@ -388,7 +388,6 @@ export interface IJupyterVariablesResponse { export const IDataViewerProvider = Symbol('IDataViewerProvider'); export interface IDataViewerProvider { create(variable: string): Promise; - getPandasVersion(): Promise<{ major: number; minor: number; build: number } | undefined>; } export const IDataViewer = Symbol('IDataViewer');