forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Detect tfevent files in workspace and prompt to launch TensorBoard #14752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
e5b0540
Prototype
joyceerhl 741c1f3
Fixes
joyceerhl de479fd
Detect tfevent files and prompt to launch tensorboard
joyceerhl 6d67e96
Format and cleanup
joyceerhl e8532a2
Prepopulate and validate logDir
joyceerhl 98fcc16
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 11d8bc7
Persist prompt state at workspace level
joyceerhl c93f0dd
Linter
joyceerhl 47d9980
Add localization keys
joyceerhl 94ef018
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 92e2150
Localization keys
joyceerhl aaf29fe
Reformat with black
joyceerhl 522b398
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl ba2d841
Weird, typescript didn't complain about this?
joyceerhl ab468aa
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 2134836
Add disposables to registry and catch errors
joyceerhl 5481d5f
Put command behind feature flag
joyceerhl ab3c322
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 158d034
Add feature flag
joyceerhl 275be2e
* Add cancellable progress indicator when starting session
joyceerhl 98166bd
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 3eca8ba
Redundant code
joyceerhl 19a31ed
Merge branch 'main' of https://github.com/microsoft/vscode-python int…
joyceerhl 5cc0a14
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl cf0757d
Whoops
joyceerhl 94afab0
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl f0328e3
More linter problems
joyceerhl bcccc19
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 53a8437
Merge branch 'main' of https://github.com/microsoft/vscode-python int…
joyceerhl 48d3648
Add news and check if in exp in provider
joyceerhl 0746bcf
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 6e82355
Don't create filewatchers if not in experiment
joyceerhl 3c2516c
Add news entry
joyceerhl 89c8294
Remove unnecessary async/await
joyceerhl 037d572
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 7c88cec
Search current dir and one level down only
joyceerhl 217be56
Fixes
joyceerhl 4176b98
Oops
joyceerhl fa7eb6a
Pass search.exclude
joyceerhl bd472fc
Merge branch 'launch-tensorboard' into tfeventfiles
joyceerhl 9de9e01
Merge branch 'main' of https://github.com/microsoft/vscode-python int…
joyceerhl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Detect tfevent files in workspace and prompt to launch native TensorBoard session. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { inject, injectable } from 'inversify'; | ||
import { FileSystemWatcher, RelativePattern, WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode'; | ||
import { IExtensionSingleActivationService } from '../activation/types'; | ||
import { IWorkspaceService } from '../common/application/types'; | ||
import { NativeTensorBoard } from '../common/experiments/groups'; | ||
import { traceError } from '../common/logger'; | ||
import { IDisposableRegistry, IExperimentService } from '../common/types'; | ||
import { TensorBoardPrompt } from './tensorBoardPrompt'; | ||
|
||
@injectable() | ||
export class TensorBoardFileWatcher implements IExtensionSingleActivationService { | ||
private fileSystemWatchers = new Map<WorkspaceFolder, FileSystemWatcher[]>(); | ||
private globPattern1 = '*tfevents*'; | ||
private globPattern2 = '*/*tfevents*'; | ||
|
||
constructor( | ||
@inject(IWorkspaceService) private workspaceService: IWorkspaceService, | ||
@inject(TensorBoardPrompt) private tensorBoardPrompt: TensorBoardPrompt, | ||
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry, | ||
@inject(IExperimentService) private experimentService: IExperimentService | ||
) {} | ||
|
||
public async activate() { | ||
if (!(await this.experimentService.inExperiment(NativeTensorBoard.experiment))) { | ||
return; | ||
} | ||
|
||
const folders = this.workspaceService.workspaceFolders; | ||
if (!folders) { | ||
return; | ||
} | ||
|
||
// Look for pre-existing tfevent files, as the file watchers will only pick up files | ||
// created or changed after they have been registered and hooked up. Just one will do. | ||
await this.promptIfWorkspaceHasPreexistingFiles(); | ||
|
||
// If the user creates or changes tfevent files, listen for those too | ||
for (const folder of folders) { | ||
this.createFileSystemWatcher(folder); | ||
} | ||
|
||
// If workspace folders change, ensure we update our FileSystemWatchers | ||
this.disposables.push( | ||
this.workspaceService.onDidChangeWorkspaceFolders((e) => this.updateFileSystemWatchers(e)) | ||
); | ||
} | ||
|
||
private async promptIfWorkspaceHasPreexistingFiles() { | ||
try { | ||
for (const pattern of [this.globPattern1, this.globPattern2]) { | ||
const matches = await this.workspaceService.findFiles(pattern, undefined, 1); | ||
if (matches.length > 0) { | ||
await this.tensorBoardPrompt.showNativeTensorBoardPrompt(); | ||
return; | ||
} | ||
} | ||
} catch (e) { | ||
traceError( | ||
`Failed to prompt to launch TensorBoard session based on preexisting tfevent files in workspace: ${e}` | ||
); | ||
} | ||
} | ||
|
||
private async updateFileSystemWatchers(event: WorkspaceFoldersChangeEvent) { | ||
for (const added of event.added) { | ||
this.createFileSystemWatcher(added); | ||
joyceerhl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
for (const removed of event.removed) { | ||
const fileSystemWatchers = this.fileSystemWatchers.get(removed); | ||
if (fileSystemWatchers) { | ||
fileSystemWatchers.forEach((fileWatcher) => fileWatcher.dispose()); | ||
this.fileSystemWatchers.delete(removed); | ||
} | ||
} | ||
} | ||
|
||
private createFileSystemWatcher(folder: WorkspaceFolder) { | ||
const fileWatchers = []; | ||
for (const pattern of [this.globPattern1, this.globPattern2]) { | ||
const relativePattern = new RelativePattern(folder, pattern); | ||
const fileSystemWatcher = this.workspaceService.createFileSystemWatcher(relativePattern); | ||
|
||
// When a file is created or changed that matches `this.globPattern`, try to show our prompt | ||
this.disposables.push( | ||
fileSystemWatcher.onDidCreate((_uri) => this.tensorBoardPrompt.showNativeTensorBoardPrompt()) | ||
); | ||
this.disposables.push( | ||
fileSystemWatcher.onDidChange((_uri) => this.tensorBoardPrompt.showNativeTensorBoardPrompt()) | ||
); | ||
this.disposables.push(fileSystemWatcher); | ||
fileWatchers.push(fileSystemWatcher); | ||
} | ||
this.fileSystemWatchers.set(folder, fileWatchers); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { inject, injectable } from 'inversify'; | ||
import { IApplicationShell, ICommandManager } from '../common/application/types'; | ||
import { Commands } from '../common/constants'; | ||
import { IPersistentState, IPersistentStateFactory } from '../common/types'; | ||
import { Common, TensorBoard } from '../common/utils/localize'; | ||
|
||
enum TensorBoardPromptStateKeys { | ||
ShowNativeTensorBoardPrompt = 'showNativeTensorBoardPrompt' | ||
} | ||
|
||
@injectable() | ||
export class TensorBoardPrompt { | ||
private state: IPersistentState<boolean>; | ||
private enabled: Promise<boolean> | undefined; | ||
private waitingForUserSelection: boolean = false; | ||
|
||
constructor( | ||
@inject(IApplicationShell) private applicationShell: IApplicationShell, | ||
@inject(ICommandManager) private commandManager: ICommandManager, | ||
@inject(IPersistentStateFactory) private persistentStateFactory: IPersistentStateFactory | ||
) { | ||
this.state = this.persistentStateFactory.createWorkspacePersistentState<boolean>( | ||
TensorBoardPromptStateKeys.ShowNativeTensorBoardPrompt, | ||
true | ||
); | ||
this.enabled = this.isPromptEnabled(); | ||
} | ||
|
||
public async showNativeTensorBoardPrompt() { | ||
if ((await this.enabled) && !this.waitingForUserSelection) { | ||
const yes = Common.bannerLabelYes(); | ||
const no = Common.bannerLabelNo(); | ||
const doNotAskAgain = Common.doNotShowAgain(); | ||
const options = [yes, no, doNotAskAgain]; | ||
this.waitingForUserSelection = true; | ||
const selection = await this.applicationShell.showInformationMessage( | ||
TensorBoard.nativeTensorBoardPrompt(), | ||
...options | ||
); | ||
this.waitingForUserSelection = false; | ||
switch (selection) { | ||
case yes: | ||
await this.commandManager.executeCommand(Commands.LaunchTensorBoard); | ||
await this.disablePrompt(); | ||
break; | ||
case doNotAskAgain: | ||
await this.disablePrompt(); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
} | ||
|
||
private async isPromptEnabled() { | ||
return this.state.value; | ||
} | ||
|
||
private async disablePrompt() { | ||
await this.state.updateValue(false); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.