-
Notifications
You must be signed in to change notification settings - Fork 300
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
Fix #10733. Support interactive window restore on window reload #10785
Conversation
// no need to update it anymore. | ||
await result.start(undefined); | ||
} else { | ||
const preferredController = connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should cache the controller id as well.
Assume user starts IW, and then changes the kernel, now they reload VS Code, the IW will point to the wrong kernel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
changes the kernel, now they reload VS Code
To double confirm, there is no "cell execution" between these two steps, right? And since there is no execution, we don't remember the kernel being used last time, so after window reloading, we still suggest previous kernel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cell execution happens after the window is created, so yeah there shouldn't be any cell execution between these two steps.
? this.controllerRegistration.get(connection, InteractiveWindowView) | ||
: await this.controllerDefaultService.computeDefaultController(resource, InteractiveWindowView); | ||
|
||
await result.start(preferredController); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should let the create
method figure out the preferred controller and pass that into the contructor.
that way we don't have two ways of starting the IW with & without arguments for the notebook controller.
Also cleaner, else the controller can be changed from outside, when i think it should be a value passed into the ctor at the point of creating the IW.
Basically i think we can move this preferedController = connection...
code into the create
method & then remove the public method start
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, agree with Don. Controller in the constructor makes the logic simpler in the class itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should let the create method figure out the preferred controller and pass that into the contructor.
that way we don't have two ways of starting the IW with & without arguments for the notebook controller
This is what InteractiveWindowProvider#create
is already doing now, it creates controller based on connection first and then create InteractiveWindow
objects. While on window reload, we create InteractiveWindow
from cache, at which point we are not in this code path of InteractiveWindowProvider#create
but in a get
path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd consider moving the code to figure out the controller into the create method as that's where we already do the dterminination, this also removes the need for the new start method (which feels weird, as it can be called with and without an arument)
Codecov Report
@@ Coverage Diff @@
## main #10785 +/- ##
========================================
- Coverage 71% 62% -9%
========================================
Files 472 476 +4
Lines 27993 33107 +5114
Branches 4691 5399 +708
========================================
+ Hits 19946 20779 +833
- Misses 6179 10285 +4106
- Partials 1868 2043 +175
|
window.tabGroups.all.forEach((group) => { | ||
group.tabs.forEach((tab) => { | ||
if (isInteractiveInputTab(tab) && tab.input.uri) { | ||
interactiveWindowMapping.set(tab.input.uri.path, tab); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have something like getkey for a uri? Would that be better than path? (Path wouldn't match say if the cases were different on windows)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rchiodo I pushed a fix to use uri.toString()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that the same as getComparisonKey?
getComparisonKey(uri: URI, ignoreFragment?: boolean): string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we need to compare Uri
s we should use getComparisonKey
which can normalize paths, here we are using it as an identifier so a toString()
is sufficient.
private _owner: Resource, | ||
private mode: InteractiveWindowMode, | ||
private readonly exportDialog: IExportDialog, | ||
private readonly notebookControllerSelection: IControllerSelection, | ||
private readonly serviceContainer: IServiceContainer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of passing the serviceContainer to constructors since it makes the class more coupled with the specific IoC container, but I suppose it's ok since it was already being passed in anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I'm not a fan either. My motivation is avoiding doing serviceContainer.get<>
in multiple places where we call InteractiveWindow#ctor
.
@DonJayamanne pointed out that it's explicit to us how many services external InteractiveWindow
import but moving serviceContainer.get<>
into ctor
kinds of hiding it. We might want to revisit this along with other challenges I ran into (will leave a comment about this soon)
Synced with @DonJayamanne offline to touch base on #10785 (comment), there are few things mixed together making it a bit complex to understand:
It would involve quite some code changes to get this right so I'd love to have them resolved in follow up PRs. One solution we discussed is
@rchiodo @IanMatthewHuff @amunger would love to have your insights into this. |
I'm not sure why create needs to be synchronous? Because the user might try to create two interactive windows at the same time? It seems the comment there has already been ignored. The problem I believe Don was trying to workaround was inside the IW class itself. If the object isn't created with a preferred controller, it then needs to do a lot of stuff async. It felt to me like async creation was better than making parts of IW async. |
@rebornix The new proposal in your last comment felt pretty legit to me (sorry, just catching up on reviews now). Per this comment it does seem that restore would not need to calculate a kernel:
Restore feels like a case where it would just handle the kernel via VS Code's controller selection memory. Calculating a preferred feels like a step that only the new case would handle. |
@@ -132,6 +156,14 @@ export class InteractiveWindowProvider | |||
if (!result) { | |||
// No match. Create a new item. | |||
result = await this.create(resource, mode, connection); | |||
// start the kernel | |||
result.start(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to just put this into the create?
Fixes #10733
With changes in this PR and microsoft/vscode#154974, users can now choose if they want to keep the interactive window on window reloads. Jupyter will now cache the interactive windows and validate them with open tabs (through the new Tab api).
This PR works when if microsoft/vscode#154974 is merged late. If VS Code part is released first, since it's turned off by default, existing users won't see any difference. We could turn the hot exit setting default value to
true
once we release changes in both products and feel comfortable of doing that.package-lock.json
has been regenerated by runningnpm install
(if dependencies have changed).