Skip to content
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

Emit events from the kernels service and gateway client #1252

Merged
merged 6 commits into from
Apr 17, 2023

Conversation

rajmusuku
Copy link
Contributor

Event emitters using Jupyter events for GatewayClient and GatewayMappingKernelManager.

Introduced event schemas for GatewayClient and GatewayMappingKernelManager
Injected jupyter event logger from jupyter_events in the above classes.
Intercepted the Restful calls into Enterprise Gateway.
Emit event messages within Jupyter server.

@welcome
Copy link

welcome bot commented Mar 31, 2023

Thanks for submitting your first pull request! You are awesome! 🤗

If you haven't done so already, check out Jupyter's Code of Conduct. Also, please make sure you followed the pull request template, as this will help us review your contribution more quickly.
welcome
You can meet the other Jovyans by joining our Discourse forum. There is also a intro thread there where you can stop by and say Hi! 👋

Welcome to the Jupyter community! 🎉

@codecov
Copy link

codecov bot commented Mar 31, 2023

Codecov Report

Patch coverage: 77.41% and project coverage change: +0.56 🎉

Comparison is base (ca4b062) 79.88% compared to head (9c5db61) 80.45%.

❗ Current head 9c5db61 differs from pull request most recent head 28bc3ab. Consider uploading reports for the commit 28bc3ab to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1252      +/-   ##
==========================================
+ Coverage   79.88%   80.45%   +0.56%     
==========================================
  Files          69       69              
  Lines        8299     8416     +117     
  Branches     1607     1635      +28     
==========================================
+ Hits         6630     6771     +141     
+ Misses       1226     1219       -7     
+ Partials      443      426      -17     
Impacted Files Coverage Δ
jupyter_server/serverapp.py 80.63% <ø> (+1.50%) ⬆️
jupyter_server/gateway/gateway_client.py 74.03% <43.33%> (-2.39%) ⬇️
jupyter_server/gateway/managers.py 85.37% <79.41%> (-0.11%) ⬇️
jupyter_server/services/kernels/kernelmanager.py 83.54% <93.33%> (+1.72%) ⬆️

... and 7 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@rajmusuku
Copy link
Contributor Author

fixes #1253 #1253

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @rajmusuku,

Thank for you opening this pull request, this is really great! I do have a concern that it introduces a schema that is specific to gateway kernel management when a general kernel management schema would be sufficient (and desired) and I think we should consider adopting a common schema for kernel management and from which GatewayKernelManager also emits events. We introduced ServerKernelManager earlier for this specific reason for non-gateway kernels.

Since this PR is beating us to the mark for generic kernel management events, I think it would be good to at least generalize the schema you have here to be the schema used for kernel management events in general. We could then extend ServerKernelManager to emit the events from the same schema.

I'd be happy to help out with this if you like. Thanks for getting this ball rolling!

@rajmusuku
Copy link
Contributor Author

@kevin-bates Thanks for your comment. It make sense to generalize the schema for Kernel service, in fact that was the initial thought to emit all the Kernel events. I would be more interested to capture failures than the regular transactions. Please let me know how can we work together on it.

@kevin-bates
Copy link
Member

Hi @rajmusuku. I think we should go ahead and generalize the kernel lifecycle event schema. I think it makes sense to include a failure indication on the events but we can talk about. We should review the generalized schema in the server and kernel meeting on Thursday.

If you'd like to get together prior to Thursday, please reach out to me via the email address associated with my GH profile. If others would like to be involved in the initial discussion, please comment with where meeting invitations can be sent.

cc: @Zsailer

@Zsailer
Copy link
Member

Zsailer commented Apr 6, 2023

Thanks for the ping, @kevin-bates. This is great!

I'll spend some time today reviewing this more closing. I've been OOO sick the past week, so I'm just now catching up.

@rajmusuku
Copy link
Contributor Author

@kevin-bates @Zsailer Pushed changes as per our conversation. Please take a look, and let me know. Thanks!

@Zsailer
Copy link
Member

Zsailer commented Apr 7, 2023

Thanks @rajmusuku!

I also push a new commit to your branch that begins emitting events from the kernel manager directly. If we agree with this approach, we can remove the emission from the MappingKernelManager.

We should also add some unit tests around these events. I'll start working on this...

@Zsailer
Copy link
Member

Zsailer commented Apr 7, 2023

Ok, I've added unit tests too 🚀

async def start_kernel(self, *args, **kwargs):
result = await super().start_kernel(*args, **kwargs)
self.emit(
schema_id="https://events.jupyter.org/jupyter_server/kernel_actions/v1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this a constant? Unlike the field names, this will likely change (per version) and seems worthy of a constant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The only reason I didn't do this was, in the future, we might have multiple kernel schemas—e.g. a kernel state schema—so I was trying to make each call to the emit(...) method explicit and decoupled. That said, I don't think that's a strong enough argument. I can make a constant for this...

@Zsailer Zsailer changed the title Event emitters using Jupyter events for GatewayClient and GatewayMappingKernelManager Event events from the kernels service and gateway client Apr 7, 2023
@Zsailer
Copy link
Member

Zsailer commented Apr 12, 2023

Thank for tracking down the codecov issue, @kevin-bates!

We can address the that mess in a separate PR. 😅

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great stuff - thank you @rajmusuku and @Zsailer!

@rajmusuku - I'm hoping you can take this for a spin in your environment where you actually have an event listener configured.

@rajmusuku
Copy link
Contributor Author

Thank you @Zsailer, @kevin-bates for your input and help. Yes, will verify it tomorrow and let you know. However, we can merge this PR.

@kevin-bates
Copy link
Member

I'm hoping you can take this for a spin in your environment where you actually have an event listener configured.

However, we can merge this PR.

Hi @rajmusuku - I made my comment because there aren't gateway-specific tests for confirming the event's emission from GatewayKernelManager. I apologize for not being more clear about that aspect but was hesitant to ask. I can try to address this today

@kevin-bates
Copy link
Member

@rajmusuku - I apologize for not getting to this yesterday. However, at closer glance, the following tests are failing as part of this PR and we should address this anyway - beyond adding code to validate emitted events...

tests/test_gateway.py::test_gateway_session_lifecycle[False] FAILED      [  3%]
tests/test_gateway.py::test_gateway_session_lifecycle[True] FAILED       [  3%]
tests/test_gateway.py::test_gateway_kernel_lifecycle[False] FAILED       [  4%]
tests/test_gateway.py::test_gateway_kernel_lifecycle[True] FAILED        [  4%]
tests/test_gateway.py::test_gateway_shutdown[True] FAILED                [  4%]
tests/test_gateway.py::test_gateway_shutdown[False] FAILED               [  4%]

These failures were lost in the general failures for the codecov snafu. I'll try to take a closer look shortly. (Right, famous last words. 😄). We'll need to hold the merge until these are resolved.

@kevin-bates
Copy link
Member

Welp, it turns out this comment was incorrect, and derivation from AsyncIOLoopKernelManager is (somehow) problematic. I'd like to better understand this before duplicating the decorator. When deriving from AILKM, we are unable to obtain an instance here:

km = self.kernel_manager_factory(parent=self, log=self.log)

@kevin-bates
Copy link
Member

Welp, it turns out #1252 (comment) was incorrect, and derivation from AsyncIOLoopKernelManager is (somehow) problematic. I'd like to better understand this before duplicating the decorator.

It (actually) turns out to have been an incompatibility between GatewayKernelManager and ServerKernelManager because the latter (correctly) types last_activity and the former was setting its value to None. I've gone ahead and set initial values (to execution_state as well) and pushed the correction. The gateway tests should pass.

I'd still like to get some event testing for gateway completed and will focus on that shortly. Sorry for the delays!

@kevin-bates kevin-bates self-requested a review April 14, 2023 20:51
@default("event_logger")
def _default_event_logger(self):
"""Initialize the logger and ensure all required events are present."""
if self.parent is not None and hasattr(self.parent, "event_logger"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Zsailer - because the event_logger trait is on the ServerKernelManager and not the AsyncMappingKernelManager, do we need the double-hop of parent to access the configurable on ServerApp here? I.e.,:

Suggested change
if self.parent is not None and hasattr(self.parent, "event_logger"):
if self.parent is not None and self.parent.parent is not None and hasattr(self.parent.parent, "event_logger"):

@rajmusuku
Copy link
Contributor Author

@Zsailer @kevin-bates Just tested with my extension, however, the event listener is not catching the emitted events. Will do some investigation and let you know.

@rajmusuku
Copy link
Contributor Author

@Zsailer @kevin-bates Just tested with my extension, however, the event listener is not catching the emitted events. Will do some investigation and let you know.

@Zsailer @kevin-bates Let's merge this PR as we are good with all the changes. I will work on more testing with my extension. Please let me know if you have any questions.

@kevin-bates
Copy link
Member

@Zsailer @kevin-bates Just tested with my extension, however, the event listener is not catching the emitted events. Will do some investigation and let you know.

@rajmusuku - how are you registering your handler on your event logger? I found that I had to use register_handler() rather than directly append it to (or set) the logger's handler array.

Let's merge this PR as we are good with all the changes.

@blink1073 - Do you have an idea regarding the code coverage stall?

@blink1073
Copy link
Collaborator

blink1073 commented Apr 17, 2023

I removed those checks from the main branch, new PRs should not have them.

@Zsailer
Copy link
Member

Zsailer commented Apr 17, 2023

Just tested with my extension, however, the event listener is not catching the emitted events. Will do some investigation and let you know.

I think we should add documentation about events in jupyter_server before merging. I'll work on this today.

@kevin-bates
Copy link
Member

@Zsailer - I'm good to go here, are you good to go here? 😄

@Zsailer
Copy link
Member

Zsailer commented Apr 17, 2023

I'm good to go here, are you good to go here?

Let me open a separate PR showing the documentation I propose.

We don't have to block on that other PR being merged, but lets at least wait until I open that documentation PR (give me a hour or two).

@Zsailer Zsailer mentioned this pull request Apr 17, 2023
1 task
@Zsailer
Copy link
Member

Zsailer commented Apr 17, 2023

Ok, I opened #1260 to begin documenting the events emitted by Jupyter Server. I'll keep that in draft state until I'm able to get the auto-generation of event schema documentation working.

In the meantime, I think this is ready to go. Merging!

@Zsailer Zsailer enabled auto-merge (squash) April 17, 2023 20:50
@Zsailer Zsailer disabled auto-merge April 17, 2023 20:50
@Zsailer Zsailer merged commit 5c49253 into jupyter-server:main Apr 17, 2023
@welcome
Copy link

welcome bot commented Apr 17, 2023

Congrats on your first merged pull request in this project! 🎉
congrats
Thank you for contributing, we are very proud of you! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants