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

feat: add switch control when watching events whether deserialization… #2369

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Kevinz857
Copy link

@Kevinz857 Kevinz857 commented Mar 7, 2025

What type of PR is this?

/kind feature
/kind optimization

What this PR does / why we need it:

This PR adds an option to disable deserialization in the Watch.stream() method to improve performance for high-frequency watch operations. When dealing with large-scale Kubernetes clusters or high-frequency resource updates, the default deserialization of every event can cause significant latency overhead and potential processing delays.

By allowing clients to opt-out of automatic deserialization when only basic JSON parsing is needed, we can significantly reduce time cost and improve event processing throughput. This is particularly important in scenarios with high event volumes or resource constraints.

Key changes:

  • Added a deserialize parameter to Watch.stream() method (defaults to True for backward compatibility)
  • When deserialize=False, events are only JSON parsed without model conversion
  • Maintains the original behavior when deserialize=True
  • Reduces CPU overhead for use cases that don't require full object models

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

The change is backward compatible and doesn't affect existing code. Users can opt-in to the performance optimization by explicitly setting deserialize=False when they don't need the full model objects.

Performance improvement example:

@k8s-ci-robot
Copy link
Contributor

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot
Copy link
Contributor

@Kevinz857: The label(s) kind/optimization cannot be applied, because the repository doesn't have them.

In response to this:

What type of PR is this?

/kind feature
/kind optimization

What this PR does / why we need it:

This PR adds an option to disable deserialization in the Watch.stream() method to improve performance for high-frequency watch operations. When dealing with large-scale Kubernetes clusters or high-frequency resource updates, the default deserialization of every event can cause significant CPU overhead and potential processing delays.

Key changes:

  • Added a deserialize parameter to Watch.stream() method (defaults to True for backward compatibility)
  • When deserialize=False, events are only JSON parsed without model conversion
  • Maintains the original behavior when deserialize=True
  • Reduces CPU overhead for use cases that don't require full object models

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

The change is backward compatible and doesn't affect existing code. Users can opt-in to the performance optimization by explicitly setting deserialize=False when they don't need the full model objects.

Performance improvement example:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Mar 7, 2025
@k8s-ci-robot
Copy link
Contributor

Welcome @Kevinz857!

It looks like this is your first PR to kubernetes-client/python 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-client/python has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Kevinz857
Once this PR has been reviewed and has the lgtm label, please assign yliaog for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label Mar 7, 2025
@Kevinz857
Copy link
Author

@fabianvf @roycaihw pls take a review when u r free , thanks a lot

event = self.unmarshal_event(line, return_type)
else:
# Only do basic JSON parsing, no deserialize
event = json.loads(line)
Copy link
Member

Choose a reason for hiding this comment

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

Here event['raw_object'] is not populated like here does, which means the retry_after_410 logic won't work.

We need to make sure the retry logic continue to work even when we don't deserialize the object

while True:
resp = func(*args, **kwargs)
try:
for line in iter_resp_lines(resp):
# unmarshal when we are receiving events from watch,
# return raw string when we are streaming log
if watch_arg == "watch":
event = self.unmarshal_event(line, return_type)
if deserialize:
event = self.unmarshal_event(line, return_type)
Copy link
Member

Choose a reason for hiding this comment

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

We actually have the return_type flag which could serve the purpose, but it looks pretty unintuitive-- IIUC _raw_return_type can be persisted by setting return_type to False, which would result in deserialization being skipped

That being said, the flag name seems unintuitive and I think deserialize = False makes more sense.

cc @yliaog

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on deserialize = False

event = self.unmarshal_event(line, return_type)
else:
# Only do basic JSON parsing, no deserialize
event = json.loads(line)
Copy link
Member

Choose a reason for hiding this comment

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

I also noticed that in this way, the resource version is not tracked like here does.

I think we can refactor the unmarshal_event method to keep track of the resource version even when we skip deserialization.

event = self.unmarshal_event(line, return_type)
else:
# Only do basic JSON parsing, no deserialize
event = json.loads(line)
Copy link
Member

Choose a reason for hiding this comment

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

Please update the tests to ensure the retry and resource version behaviors when deserialize = False

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Mar 14, 2025
@Kevinz857
Copy link
Author

Kevinz857 commented Mar 14, 2025

Thank's ur comments , Setting the deserialize default value to false is actually more appropriate, adjust this and add test code commit . Pls take a look again , thanks @roycaihw @yliaog

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 22, 2025
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. kind/feature Categorizes issue or PR as related to a new feature. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants