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

Make RequestsClient thread-safe #531

Merged
merged 1 commit into from
Jan 30, 2019
Merged

Conversation

brandur
Copy link
Contributor

@brandur brandur commented Jan 29, 2019

It came up in #526 that our implementation isn't quite thread-safe.
Most HTTP clients are by virtue of the fact that their underlying
libraries are, but the recommended client, RequestsClient for the
Requests library, creates and reuses only a single session for all the
requests it makes.

The Requests maintainers are non-committal when it comes to the thread
safety of a session, but the general sentiment of its userbase is that
sessions are not thread safe.

Here we tweak the RequestsClient implementation so that we create one
session per thread by leveraging Python's thread-local storage.

Unfortunately, this implementation still leaves a pitfall in that if you
explicitly pass in a session in, it will get used between all threads.
The ideal thing to do here I think would be to probably not accept a
session object anymore, but that'd be a breaking change. One possibility
is that we could start warning about the use of the session parameter,
but for the time being I've opted to just leave this as a known problem
(given that hopefully this patch will still be a strict improvement).

Note this will conflict with #530, but rebasing either branch should be
simple.

r? @ob-stripe
cc @jameshageman-stripe
cc @stripe/api-libraries

It came up in #526 that our implementation isn't quite thread-safe.
*Most* HTTP clients are by virtue of the fact that their underlying
libraries are, but the recommended client, `RequestsClient` for the
Requests library, creates and reuses only a single session for all the
requests it makes.

The Requests maintainers are non-committal when it comes to the thread
safety of a session, but the general sentiment of its userbase is that
sessions are not thread safe.

Here we tweak the `RequestsClient` implementation so that we create one
session per thread by leveraging Python's thread-local storage.

Unfortunately, this implementation still leaves a pitfall in that if you
explicitly pass in a session in, it will get used between all threads.
The ideal thing to do here I think would be to probably not accept a
session object anymore, but that'd be a breaking change. One possibility
is that we could start warning about the use of the session parameter,
but for the time being I've opted to just leave this as a known problem
(given that hopefully this patch will still be a strict improvement).
Copy link
Contributor

@ob-stripe ob-stripe left a comment

Choose a reason for hiding this comment

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

LGTM!

@ob-stripe ob-stripe merged commit f1b4260 into master Jan 30, 2019
@ob-stripe ob-stripe deleted the brandur-thread-safe-clients branch January 30, 2019 10:16
@ob-stripe
Copy link
Contributor

Released as 2.20.1.

@brandur-stripe
Copy link
Contributor

Thanks OB!

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