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
chore(internal): move rate limiter to PyO3 #9232
base: main
Are you sure you want to change the base?
Conversation
I am having an issue with a test, I cannot figure out how to resolve.
|
Datadog ReportBranch report: ✅ 0 Failed, 174625 Passed, 1086 Skipped, 11h 50m 47.27s Total duration (18m 55.5s time saved) |
…ontext (#9272) This PR introduces two main changes: 1. Do not reset `_DD_CONTEXTVAR` when initializing a `DefaultContextProvider` 2. Explicitly clear `_DD_CONTEXTVAR` after every test in dd-trace-py CI 1. We also emit a warning, so pytest will show them to us ## Motivation Currently, when 1. asyncio auto instrumentation is patched 5. and there's an existing trace context 6. and `asyncio` is imported Then the existing trace context will be reset to None. The expected behavior is that the existing trace context should not be reset for this kind of lazy imports ## Checklist - [x] Change(s) are motivated and described in the PR description - [x] Testing strategy is described if automated tests are not included in the PR - [x] Risks are described (performance impact, potential for breakage, maintainability) - [x] Change is maintainable (easy to change, telemetry, documentation) - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed or label `changelog/no-changelog` is set - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)) - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) - [x] If this PR changes the public interface, I've notified `@DataDog/apm-tees`. ## Reviewer Checklist - [ ] Title is accurate - [ ] All changes are related to the pull request's stated goal - [ ] Description motivates each change - [ ] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - [ ] Testing strategy adequately addresses listed risks - [ ] Change is maintainable (easy to change, telemetry, documentation) - [ ] Release note makes sense to a user of the library - [ ] Author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - [ ] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --------- Co-authored-by: Brett Langdon <brett.langdon@datadoghq.com>
ba01eda
to
60d13bd
Compare
This change is made. |
@@ -0,0 +1,20 @@ | |||
[package] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having these files live in internal/core
would follow a pattern that's used for other subpackages containing native code, making this new code easier to learn. Is that technically straightforward enough to try?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easy enough to try.
I think the general pattern other repositories take is:
- package_name
- __init__.py
- _native.so
- src
- native.c
- pyproject.toml
https://github.com/pola-rs/polars/tree/main/py-polars
Just because others are doing it, doesn't mean we need to.
Eventually I'd like to see core stuff broken out into it's own package, rather than module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something feels weird about it to me, but yes we can. Let me know if you'd prefer me to update it to nest under internal/core/
This PR sets up a new
ddtrace.internal._core
module which is a Rust module defined insrc/core/
and uses PyO3.The first component being moved over is the
ddtrace.internal.rate_limiter.RateLimter
.This is a well isolated component which has minimal need to be in Python. There are clear performance gains from moving this component to native.
The main motivation from this change is to start to build the basis for adding/moving performance critical components to PyO3.
Risks
This introduces a requirement on the rust compiler for building from source. We have built this into our dev image for awhile, but there are other places where we do not yet have the proper setup and so processes may fail.
For example, the benchmarking platform image does not have rust compiler yet.
Testing
Since we kept the same public interface as the original Python module, we are using the existing Python tests as the validation of this change. They should be comprehensive enough to validate the new native version.
Benchmarks
The benchmarking image is not yet updated to include rust compiler, so the following results are from running locally on my machine only.
The new
rate_limiter
benchmark shows a roughly 4x performance improvement.This is a great improvement, however, the rate limiter is such a small portion of an actual trace, because right now it's biggest impact is on starting a new trace and making a sampling decision. So applications with the biggest possible improvement are those which start a lot of small traces at high volume.
Benchmarks for the
span
suite show a minor improvement, this is because the rate limiter today only takes up a small portion of the total lifecycle of a span.Benchmarks for the
tracer
suite showing similar results tospan
.tracer-large
results are not show a statistically significant enough difference in overhead.Benchmarks for the
flask_simple
suite showing almost no improvement at all.Follow-up future work
Checklist
changelog/no-changelog
is set@DataDog/apm-tees
.Reviewer Checklist