-
Notifications
You must be signed in to change notification settings - Fork 221
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
Making RemoteKernelManager more independent #803
Comments
@golf-player - thanks for opening this issue. I think this could be pretty cool. I think it would be good to understand what aspects of configuration are used "under" RMK. I know most of it is global information that can also be overridden at the kernelspec level and, for this use case, it might make sense that we only support the kernelspec-specified options only. This implies we might want to tolerate "null-ness" in some of the lower areas where the global and local definitions are consulted. We should identify which config items are not locally supported and determine if a tolerance to null is sufficient for those items. Do you mind taking a look? I'm happy to guide and answer questions along the way. |
@kevin-bates thanks for the reply I'm don't understand what you mean by configuration used "under" RMK. Are you asking about a minimal set of config that fully configures RMK? Which kernelspec are we talking about specifically? Different processproxies have different kernelspecs right? I'm currently basing everything I'm doing on the python in kubernetes kernelspec. All that needs is a kernel_id and response_address. As for configuration required to get RMK to run, I'm able to run kernels with the following config object passed to RKM as
It needs Logs are a good idea as well, but aren't necessary. I would assume the first step to making it more independent would be to make it agnostic of the call hierarchy via the traitlet Q: What do you mean when you ask which config items are not locally supported? |
Hi @golf-player - thanks for the great response. Yes, this is what I'm driving at. Many of these config items can actually appear in the process-proxy stanza of the kernelspec and that's what I mean by locally supported. For configuration items that cannot be supported locally, there's isn't really any "carrier" for those items. Of the items you list, all but Looking through the various references to
where RMK is extended with something like this (and as appropriate for each item)... @property
def unauthorized_users(self):
if self.parent and self.parent.parent:
unauthorized_users = self.parent.parent.authorized_users
else: # external mode
unauthorized_users = os.getenv("RMK_UNAUTHORIZED_USERS", 'root').split(',')
return unauthorized_users This would alleviate all the null checks throughout. How does that sound? I think a bit more will be necessary for the "parent" references that result in access to a class like this:
will require a check of the property first...
Regarding kernel-id, I think we need to do something similar to what you have above...
Sidebar: |
I didn't know about the kernelspec proxy stanza supporting config, so that's great. I'll be working on an MR tonight. Outstanding question is how, in the case of a RKM instance being instantiated from nbclient, does the kernel_id get passed? Maybe if the kernel_id isn't passed or set, it's lazily generated or something? But that would require kernel_id generation code to reside in the RKM (but to me this isn't a big deal as it's just using uuid) We're setting impersonation off; not sure why it's true above lol |
Hmm another thing I forgot is that the "locally supported" config items are required by RKM, not by the kernel, so at the point they're required, the kernel config isn't in the picture yet. I could probably read it from the kernelspec manager, but that doesn't seem like a good way here. |
This seems like an issue. The location of kernelspecs is also something the kernelspec manager determines and then you'd also need to load the file, reference the resources - things the kernelspec manager does. This is also where the command to launch the kernel comes from and is used by jupyter_client code. |
It just occurred to me, after re-reading the opening description, that what is passed to nbclient is a class, not an instance of a class. This is worse than I thought since, as you show, the constructor is accessing other globally defined instances, etc. I would not be opposed to defining a wrapper class that contains an instance of RemoteKernelManager and have this wrapper class's constructor instantiate a kernelspec manager, create the kernel_id, etc. then return the actual RemoteKernelManager instance - or define methods that forward to the contained instance. This way, that class could be passed to nbclient and its construtor would replace the need for the global instance. (I suspect you're already thinking this way and I'm just catching up. 😄) I think the work to convert to properties or whatever at the RemoteKernelManager level would still be useful in this approach, although you could seed the |
I think using parent makes sense when there's some guarantees about what parent is. Any RKM is guaranteed to have either no parent or an RMKM-like object, right? In this case, there were problems because the code assumed a chain of JEG->RMKM->RKM. If we're making RKM independent, in this case, I think it should have 2 sets of behaviour: 1, when it's attached to an RMKM, and 2, when it's not (I mention something like this here: #810 (comment))
|
OK I messed up a bit. Now I get what you were worried about with traitlets. I completely misunderstood how that worked. I'm looking deeper to see if I can get the mixin to work, but if not, I'll have to change that to a bunch of Sorry, but can you hold off on code review for now? |
Yeah, no worries at all. |
Make RemoteKernelManager (RKM) able to be run without a (grand)parent EnterpriseGatewayApp (EGA) instance so it can be used by nbclient. The config which RKM with EGA was being referred to using traitlet lineage like `self.parent.parent.property_name`. Change both to inherit from a Configurable mixin which contains all of EGA's previous config. Link the attributes of the RKM instance with EGA if available to keep old behaviour. Modify other properties RKM uses that are not traits to become `@property`s which fall back to sane defaults if running independently. Change RKM to be able to generate a kernel id if necessary. Change ProcessProxy to use provided kernel ids. Move kernel id generation logic out of RemoteMappingKernelManager. Resolves jupyter-server#803
Make RemoteKernelManager (RKM) able to be run without a (grand)parent EnterpriseGatewayApp (EGA) instance so it can be used by nbclient. The config which RKM with EGA was being referred to using traitlet lineage like `self.parent.parent.property_name`. Change both to inherit from a Configurable mixin which contains all of EGA's previous config. Link the attributes of the RKM instance with EGA if available to keep old behaviour. Modify other properties RKM uses that are not traits to become `@property`s which fall back to sane defaults if running independently. Change RKM to be able to generate a kernel id if necessary. Change ProcessProxy to use provided kernel ids. Move kernel id generation logic out of RemoteMappingKernelManager. Resolves jupyter-server#803
Make RemoteKernelManager (RKM) able to be run without a (grand)parent EnterpriseGatewayApp (EGA) instance so it can be used by nbclient. The config which RKM with EGA was being referred to using traitlet lineage like `self.parent.parent.property_name`. Change both to inherit from a Configurable mixin which contains all of EGA's previous config. Link the attributes of the RKM instance with EGA if available to keep old behaviour. Modify other properties RKM uses that are not traits to become `@property`s which fall back to sane defaults if running independently. Change RKM to be able to generate a kernel id if necessary. Change ProcessProxy to use provided kernel ids. Move kernel id generation logic out of RemoteMappingKernelManager. Resolves jupyter-server#803
Original thread: jupyter/nbclient#26
Some config-related issues that crop up using RKM (RemoteKernelManager) for one-off executions with nbclient/nbconvert:
kernel_id
for pod name and connection file. As discussed on the other thread, the concept ofkernel_id
is only in the context of MultiKernelManager, so maybe there could be an option for oneoffs to make essentially the same thing as a kernel_id, but call it differently to avoid confusion?@kevin-bates suggested using the kernel provider architecture here, but that seems to not be accepted, and there'd be some work to be done to get RKM to use the kernel provider. I'm gonna read through kernel providers to get some kind of understanding of how this would work.
Pasting in the code from the other thread here.
For me, ideally this would work by just setting the kernel_manager_class=RemoteKernelManager without the weird config stuff I'm forced to do otherwise.
I'm happy to do the work on this one btw, I'm just not sure how y'all prefer to make this sort of change; Do I just add a bunch of config to RKM and make fallback values for everything that's not automatically present? Since RKM expects to have a traitlets parent chain like JEG App -> RemteMappingKernelManager -> RKM, there's a lot of code accessing
parent.parent
which I would change to work with RKM's own config, which accepts the values from parent.parent if available.The text was updated successfully, but these errors were encountered: