private async ensurePrerequisitesAreInstalled()

in src/client/tensorBoard/tensorBoardSession.ts [189:290]


    private async ensurePrerequisitesAreInstalled() {
        traceInfo('Ensuring TensorBoard package is installed into active interpreter');
        const interpreter =
            (await this.interpreterService.getActiveInterpreter()) ||
            (await this.commandManager.executeCommand('python.setInterpreter'));
        if (!interpreter) {
            return false;
        }

        // First see what dependencies we're missing
        let [tensorboardInstallStatus, profilerPluginInstallStatus] = await Promise.all([
            this.installer.isProductVersionCompatible(Product.tensorboard, TensorBoardSemVerRequirement, interpreter),
            this.installer.isProductVersionCompatible(
                Product.torchProfilerImportName,
                TorchProfilerSemVerRequirement,
                interpreter,
            ),
        ]);
        const isTorchUser = ImportTracker.hasModuleImport('torch');
        const needsTensorBoardInstall = tensorboardInstallStatus !== ProductInstallStatus.Installed;
        const needsProfilerPluginInstall = profilerPluginInstallStatus !== ProductInstallStatus.Installed;
        if (
            // PyTorch user, in profiler install experiment, TensorBoard and profiler plugin already installed
            (isTorchUser && !needsTensorBoardInstall && !needsProfilerPluginInstall) ||
            // Not PyTorch user or not in profiler install experiment, so no need for profiler plugin,
            // and TensorBoard is already installed
            (!isTorchUser && tensorboardInstallStatus === ProductInstallStatus.Installed)
        ) {
            return true;
        }

        // Ask the user if they want to install packages to start a TensorBoard session
        const selection = await this.promptToInstall(
            tensorboardInstallStatus,
            isTorchUser ? profilerPluginInstallStatus : ProductInstallStatus.Installed,
        );
        if (selection !== Common.bannerLabelYes() && !needsTensorBoardInstall) {
            return true;
        }
        if (selection !== Common.bannerLabelYes()) {
            return false;
        }

        // User opted to install packages. Figure out which ones we need and install them
        const tokenSource = new CancellationTokenSource();
        const installerToken = tokenSource.token;
        const cancellationPromise = createPromiseFromCancellation({
            cancelAction: 'resolve',
            defaultValue: InstallerResponse.Ignore,
            token: installerToken,
        });
        const installPromises = [];
        // If need to install torch.profiler and it's not already installed, add it to our list of promises
        if (needsTensorBoardInstall) {
            installPromises.push(
                this.installer.install(
                    Product.tensorboard,
                    interpreter,
                    installerToken,
                    tensorboardInstallStatus === ProductInstallStatus.NeedsUpgrade
                        ? ModuleInstallFlags.upgrade
                        : undefined,
                ),
            );
        }
        if (isTorchUser && needsProfilerPluginInstall) {
            installPromises.push(
                this.installer.install(
                    Product.torchProfilerInstallName,
                    interpreter,
                    installerToken,
                    profilerPluginInstallStatus === ProductInstallStatus.NeedsUpgrade
                        ? ModuleInstallFlags.upgrade
                        : undefined,
                ),
            );
        }
        await Promise.race([...installPromises, cancellationPromise]);

        // Check install status again after installing
        [tensorboardInstallStatus, profilerPluginInstallStatus] = await Promise.all([
            this.installer.isProductVersionCompatible(Product.tensorboard, TensorBoardSemVerRequirement, interpreter),
            this.installer.isProductVersionCompatible(
                Product.torchProfilerImportName,
                TorchProfilerSemVerRequirement,
                interpreter,
            ),
        ]);
        // Send telemetry regarding results of install
        sendTelemetryEvent(EventName.TENSORBOARD_PACKAGE_INSTALL_RESULT, undefined, {
            wasTensorBoardAttempted: needsTensorBoardInstall,
            wasProfilerPluginAttempted: needsProfilerPluginInstall,
            wasTensorBoardInstalled: tensorboardInstallStatus === ProductInstallStatus.Installed,
            wasProfilerPluginInstalled: profilerPluginInstallStatus === ProductInstallStatus.Installed,
        });
        // Profiler plugin is not required to start TensorBoard. If it failed, note that it failed
        // in the log, but report success only based on TensorBoard package install status.
        if (isTorchUser && profilerPluginInstallStatus !== ProductInstallStatus.Installed) {
            traceError(`Failed to install torch-tb-plugin. Profiler plugin will not appear in TensorBoard session.`);
        }
        return tensorboardInstallStatus === ProductInstallStatus.Installed;
    }