jupyter / jupyter_client

Jupyter protocol client APIs
https://jupyter-client.readthedocs.io
BSD 3-Clause "New" or "Revised" License
388 stars 283 forks source link

Who picks KernelManager class? #301

Open takluyver opened 7 years ago

takluyver commented 7 years ago

The new kernel discovery machinery added in #261 allows a kernel provider to return an instance of KernelManager or a subclass when a frontend wants to start a kernel. This is meant to allow flexibility such as launching a kernel on a remote machine.

However, while working on the Qt console I remembered that it starts kernels through its own QtKernelManager subclass, which integrates with the Qt framework (e.g. using Qt signals for events). So it would be incompatible with the kernel discovery framework, because the managers it gets from that will not be Qt managers.

Options

  1. Let the application pick the KernelManager subclass, and scale back the discovery framework to return declarative information for starting a kernel (i.e. argv & env).
  2. Split out a defined subsection of the KernelManager API to be picked by the kernel provider, which slots into the remaining KernelManager picked by the application.
  3. Let the discovery framework pick the KernelManager subclass, and say that applications that need a different interface are responsible for wrapping the object they get back. (more or less the same as 2, but pushes the responsibility more to applications)
  4. Add to the discovery framework so that applications can request e.g. a Qt-compatible kernel manager. I only see downsides to this - it makes it an n*m problem, and is bound to lead to compatibility headaches.

I would say that option 2 is neatest if we can figure cleanly separating two API layers, but I'm not sure we can. If not, option 1 is probably the fallback.

minrk commented 6 years ago

I would like the discovery mechanism to be able to pick the KernelManager, because I really want to have things like remote kernels that don't involve shelling out to subprocesses, which I think is the wrong approach for remote kernels, and the provider ought to be able to be responsible for port selection as well, which is easier if it can specify the KernelManager.

Looking at qtconsole, there is very little in QtKernelManager, and I think that probably be handled via fairly clear over-the-top mechanisms instead of the mixin subclassing we do in QtConsole. Most of the logic is really in the KernelClient, which the application does need to control. So I think we should examine this from the QtConsole perspective, where:

  1. provider picks KernelManager
  2. QtConsole can register its own restart logic
  3. QtConsole can easily instantiate its own QtKernelClient

As long as these are things that the QtConsole can accomplish, we should be okay. Or is there something else?

We could try to more clearly isolate what a custom KernelManager might do by defining a separate class, but I think defining the appropriate base set of methods to define ought to be enough.