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

Migrate Django middleware to new-style #533

Merged

Conversation

adamantike
Copy link
Contributor

@adamantike adamantike commented Jun 5, 2021

Description

New-style middlewares were introduced in Django 1.10, and also settings.MIDDLEWARE_CLASSES was removed in Django 2.0.

This change migrates the Django middleware to conform with the new style, from Django 2.0 onwards. This is useful because it will help us solve the pending issue in #391.

By having a single entrypoint to the middleware, __call__, which is wrapped with sync_to_async just once for async requests, we avoid the issue where a ContextVar cannot be reset from a different context.

With the current deprecated MiddlewareMixin way, both process_request and process_response were being wrapped separately with sync_to_async, which was the source of the mentioned issue.

It's worth mentioning that this change maintains compatibility with legacy Django versions.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • tox -e test-instrumentation-django

Does This PR Require a Core Repo Change?

  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

New-style middlewares were [introduced][django_1_10_changelog] in Django
`1.10`, and also `settings.MIDDLEWARE_CLASSES` was
[removed][django_2_0_changelog] in Django 2.0.

This change migrates the Django middleware to conform with the new
style. This is useful because it will help us solve the pending issue in
open-telemetry#391.

By having a single entrypoint to the middleware, `__call__`, which is
[wrapped with `sync_to_async` just once][call_wrapped] for async
requests, we avoid the [issue][asgiref_issue] where a `ContextVar`
cannot be reset from a different context.

With the current deprecated `MiddlewareMixin` way, both `process_request`
and `process_response` were being
[wrapped separately with `sync_to_async`][mixin_wrapped], which was the
source of the mentioned issue.

[django_1_10_changelog]: https://docs.djangoproject.com/en/3.2/releases/1.10/#new-style-middleware
[django_2_0_changelog]: https://docs.djangoproject.com/en/3.2/releases/2.0/#features-removed-in-2-0
[call_wrapped]: https://github.com/django/django/blob/213850b4b9641bdcb714172999725ec9aa9c9e84/django/core/handlers/base.py#L54-L57
[mixin_wrapped]: https://github.com/django/django/blob/213850b4b9641bdcb714172999725ec9aa9c9e84/django/utils/deprecation.py#L137-L147
[asgiref_issue]: django/asgiref#267
@adamantike adamantike requested a review from a team as a code owner June 5, 2021 00:24
@adamantike adamantike requested review from owais and lzchen and removed request for a team June 5, 2021 00:24
@adamantike adamantike mentioned this pull request Jun 5, 2021
7 tasks
@owais
Copy link
Contributor

owais commented Jun 5, 2021

I don't think this is a good enough reason to drop support for older versions even if they aren't supported by their authors anymore. This is 9 versions we'll be dropping support for here. The upside doesn't seem to be worth it.

I think we have two choices here:

  1. Implement both old and new style middlewares. Use new style for 1.10+ and old one for <1.10
  2. Wait for this proposal to be implemented and then remove support for <1.10 in a future version. It'll allow users to use older instrumentation version with newer API/SDK packages. This means that opentelemetry-instrumentation will have to 1.0 as well though.

If we really want to use new style middlewares, I'd recommend to go with option 1. today.

@adamantike
Copy link
Contributor Author

This is 9 versions we'll be dropping support for here.

I agree with trying to maintain support for legacy library versions as much as possible. However, there are a few more considerations to bring to the table:

That being said, I've updated the PR to fallback to inheriting from deprecated MiddlewareMixin for older Django versions. I've found other unrelated issues that won't let those Django versions to correctly instrument OpenTelemetry, but I plan to tackle those in separate PRs.

@adamantike adamantike force-pushed the django-new-style-middleware branch from 44da1cb to c9614bb Compare June 5, 2021 04:38
@adamantike
Copy link
Contributor Author

@owais, please let me know what do you think about this approach, when you get the time to review it.

@adamantike
Copy link
Contributor Author

Gentle ping, to be able to move forward with #391

@adamantike
Copy link
Contributor Author

@owais, can you please review this PR again?

@adamantike
Copy link
Contributor Author

Updated to fix changelog's conflict.

Copy link
Contributor

@codeboten codeboten left a comment

Choose a reason for hiding this comment

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

@owais is this another case for having different packages for different supported versions as mentioned here #550?

@owais
Copy link
Contributor

owais commented Jul 1, 2021

@codeboten I think a single package makes more sense. I'll share my thoughts and preferences in the issue you linked. For this PR, I think the use case is too simple to warrant a new package. I think we should not block this PR for #550.

@adamantike
Copy link
Contributor Author

I have resolved merge conflicts again. Is there anything else I can do to move forward with this PR?

Copy link
Contributor

@codeboten codeboten left a comment

Choose a reason for hiding this comment

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

Thanks for getting this PR in 👍!

@codeboten codeboten merged commit b2802dd into open-telemetry:main Jul 6, 2021
@adamantike adamantike deleted the django-new-style-middleware branch July 6, 2021 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants