dotnet / interactive

.NET Interactive combines the power of .NET with many other languages to create notebooks, REPLs, and embedded coding experiences. Share code, explore data, write, and learn across your apps in ways you couldn't before.
MIT License
2.8k stars 371 forks source link

Is a kernel per user split a good idea ? #3577

Open PawelStadnicki opened 2 weeks ago

PawelStadnicki commented 2 weeks ago

TLDR: Is there a limit to the number of kernels in a composite kernel? Is managing a large number of them scalable?

While waiting for good Wasm usability (multithreading support, large load of all necessary files, etc.) to use .NET Interactive in Client-Blazor, I'm switching my experiments to Server-Blazor.

My use case: The user has access to plenty of common/predefined variables available immediately for all users and then runs their own code. Users also have access to their specific preloaded variables available only to them.

For example, I have data for the London area and subway stations available to everyone, and private places (current job, school) available only to specific users.

I wonder if I could create a copy of an (F#) kernel for each user by adding them to a composite kernel. Such a copy could receive (via share) access to common variables and receive their private data for their use. I would remove these kernels after some time when the users stop executing them.

I am aware there is a potential for vulnerability/malicious code that I should protect against, but that is not part of this question. I am seeking the simplest possible scalable pattern to allow a number of users to share one (theoretically powerful, with a lot of CPUs and memory) app service. I believe I don't want something similar to GitHub Codespaces, where a user may "provision" their own environment.

I also know that the F# kernel locks internal access to a script engine, and even with a powerful server, it may not be super scalable. However, having dozens of parallel (64-128) interactive engines should be sufficient. Is a kernel/composite a lightweight enough structure for that purpose?

@jonsequitur @colombod

jonsequitur commented 1 week ago

I don't know that the number of kernels in and of itself would be an issue but we've never done any perf tests on this kind of scenario.

The first thing that comes to mind though is the scheduling model. Under a single composite kernel, all subkernels share a scheduler by default, and commands are queued so that parallelism isn't introduced. You can of course write code that goes parallel. So the default scheduling behavior would be a by-design bottleneck for your scenario.

But this behavior can be altered. Here are a few approaches that can work today:

With a few modifications, the following would also be possible: