Description
openedon May 10, 2022
This is a follow up of API discussions around proxy controller #146942. The original attempt was introducing a new type of controllers NotebookProxyController
which offers a resolver handler resolveHandler: () => NotebookController | Thenable<NotebookController>
.
As discussed offline with @jrieken, an alternative is allowing the existing NotebookController
to be async by introducing an optional connectionState
and making the proxy kernel a special scenario.
The NotebookController
will have a new property
export interface NotebookController {
connectionState?: NotebookConnectionState
}
Existing controllers
For notebook controllers which don't have an async connecting/set-up phase, they can ignore the property (leaving it `undefined). This would be backwards compatible.
Lazy/Async controllers
For notebook controllers which require some long running connection or setup, when users run cells, they
- Change the
connectionState
toconnecting
. - When connection/setup finishes, flip back the
connectionState
toconnected
oridle
. - Create
NotebookCellExecution
to start the real cell execution.
Proxy controllers
This would be a special case. The difference between lazy controller and proxy controller is, proxy controller represents a set of kernels which are only known after required steps (authentication, connecting to the server, detecting kernels on the server, etc), while lazy controller is representing an known kernel, but it requires additional steps to connect to the kernel.
Take the github workflow (described in #146942) as example, we would create a controller called "GitHub" first and after doing authentication, spinning up jupyter server, we will get a real Python kernel. Currently the core relies on the NotebookController.id
to be unique and meaningful (e.g., it stores which controller is used last time in global memento by controller id), to ensure that the real Python kernel can be remembered by VS Code and picked automatically if users reload the workbench, we want to pass the responsibility of cell execution from the GitHub controller to the Python controller.
To express this, we need to add a new state to NotebookConnectionState
to differentiate proxy and lazy kernels
export interface NotebookConnectionState {
Idle,
Connecting,
Delegate
}
When current active notebook controller changes its state to Delegate
, the core will then find another preferred controller (we can have limitations for this, like only searching in the controllers from the same extension) and use that to execute code.