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

High CPU Odata Usage AddWithResize() #3015

Closed
haledv opened this issue Jul 15, 2024 · 3 comments
Closed

High CPU Odata Usage AddWithResize() #3015

haledv opened this issue Jul 15, 2024 · 3 comments
Assignees

Comments

@haledv
Copy link

haledv commented Jul 15, 2024

We are using Odata to query data, and we noticed some high CPU usages when the Api gets hit by some medium traffic.

Assemblies affected

Microsoft.OData.Client" Version="7.20.0"
Microsoft.OData.Extensions.Client" Version="1.0.6"

Actual result

CPU Spikes

Additional detail

I am not sure if we are using the Client somehow wrong or something special, but tracing the application revelead that the cpu is mostly burned here:

image

If someone has any tips on what to look for when the stack trace looks like that.

@habbes
Copy link
Contributor

habbes commented Jul 16, 2024

@haledv Thanks for sharing the profiler screenshot. Does this spike occur throughout, over multiple requests, or just during the first request? Do you create a new DataServiceContext per request? The LoadServiceModelFromNetwork call that appears in the screenshot usually occurs when the DataServiceContext is trying to load the IEdmModel and no custom loader has been defined.

If you generated your client using OData Connected Service or OData CLI, this should not occur, since they also generate a customer loader. Could you share more details or code snippets of how your DataServiceContext is constructed and configured?

If you created a custom DataServiceContext manually (without using our code generation tools), then you should configure configure the DataServiceContext.Format with a customer service model loader as suggested in this article: https://learn.microsoft.com/en-us/odata/client/using-poco-classes#loading-the-service-model

Namely, you should override the DataServiceContext.Format.LoadServiceModel property with a custom method or delegate that returns the instance of IEdmModel that represents the service's schema. Ideally this should not perform repeated network call or parsing on each call. The model should be loaded and parsed once the cached in some static field for later retrieval.

context.LoadServiceModel =() => GetParsedEdmModel();
context.UseJson();

This setup should happen before the first request is made by the DataServiceContext.

You can parse an IEdmModel from a string or stream using CsdlReader: https://learn.microsoft.com/en-us/odata/odatalib/edm/read-write-model#using-the-csdlreader-apis

@haledv
Copy link
Author

haledv commented Jul 21, 2024

Hi, thx for the quick reply.

It occured while multiple requests where sent at once, which came from a user burst on the facing API.

It was created manually without the CLI. Following your advice and the links provided, we cached the Edm Model so no repeated network calls where done and it solved the Problem completely. No more redudant Network Calls and CPU spikes have gone.

Thank for the Advice!

@habbes
Copy link
Contributor

habbes commented Jul 23, 2024

Thanks @haledv for getting back. We should add this to our performance guidelines: MicrosoftDocs/OData-docs#318

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

No branches or pull requests

3 participants