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

Add context.Context support #357

Closed
derekperkins opened this issue Jan 4, 2017 · 9 comments
Closed

Add context.Context support #357

derekperkins opened this issue Jan 4, 2017 · 9 comments
Labels

Comments

@derekperkins
Copy link

For all the network calls made in this package, it would be nice to be able to use context.Context as the first parameter to all the calls, allowing for program control over cancelation deadlines, metrics and all the other good things that come along with it.

@brandur
Copy link
Contributor

brandur commented Jan 5, 2017

That would be cool.

Unfortunately, I think you'd want to be able to supply a Context as a parameter for every single HTTP call currently in the library, which would necessitate some pretty heavy refactoring here.

Tagging this as "future" for now.

@brandur brandur added the future label Jan 5, 2017
@pjebs
Copy link

pjebs commented Jan 18, 2017

Also bear in mind that Google App Engine users still only have access to: golang.org/x/net/context AND NOT context.Context since GAE runtime is still officially using Go1.6

@derekperkins
Copy link
Author

@pjebs That's only for the next few weeks until GAE adds support for 1.8.

@klauspost
Copy link
Contributor

klauspost commented Oct 17, 2017

Without knowing the details, I could see this fairly simple implementation:

First of all, add it to the common parameters:

// Params is the structure that contains the common properties
// of any *Params structure.
type Params struct {
	// Context used for request.
	Context context.Context `form:"-"`

Package users then simply adds the context to the parameters they send.

To add it to all requests is then simply a matter of adding it to the Call interface of the Backend:

	req, err := s.NewRequest(method, path, key, "application/x-www-form-urlencoded", body, params)
	if err != nil {
		return err
	}
	if params.Context != nil {
		req = req.WithContext(params.Context)
	}

	if err := s.Do(req, v); err != nil {
		return err
	}
  • similar thing in CallMultipart.

AFAICT this is backwards compatible and allows sending a custom context to each request. It requires Go 1.8 of course.

It is not idiomatic, but it doesn't require you to have all calls duplicated like client.NewContext(ctx context.Conrext, params *stripe.SKUParams) (*stripe.SKU, error), etc.

brandur-stripe pushed a commit that referenced this issue Oct 17, 2017
Supports the `Context` struct [1] that came in with Go 1.7 on Stripe API
requests. This can be used to carry deadlines, cancelation signals, and
other request-scoped values across API boundaries and between processes.

Fixes #357.

[1] https://golang.org/pkg/context/
@brandur-stripe
Copy link
Contributor

Good point Klaus! I've added an implementation based on your suggestion in #477. Thanks.

AFAICT this is backwards compatible and allows sending a custom context to each request. It requires Go 1.8 of course.

Good news on that front even! Context came in as part of 1.7, so all the version of Go in our matrix can support the change.

@brandur-stripe
Copy link
Contributor

And actually, if anyone on here would be willing to take a quick look at #477 just to see what they think from an API perspective, it'd be greatly appreciated. I'll hold merging it a few days to see if we can gather a little feedback.

brandur-stripe pushed a commit that referenced this issue Oct 18, 2017
Supports the `Context` struct [1] that came in with Go 1.7 on Stripe API
requests. This can be used to carry deadlines, cancelation signals, and
other request-scoped values across API boundaries and between processes.

Fixes #357.

[1] https://golang.org/pkg/context/
@jmhodges
Copy link

An alternative is to work like database/sql and add Context versions of the methods under a different (but similar) name. That style seems to be more common (and avoids the "don't put Contexts in structs" review comments).

@klauspost
Copy link
Contributor

klauspost commented Oct 18, 2017

like database/sql

Yeah, but that would require duplicating all methods on all clients and also do it for the "client-less" functions in each package. A rough estimate is 280 duplicated functions.

A func (p *Params) WithContext(c context.Context) *Params could be added that returns a shallow copy with a context similar to (http.Request).WithContext. I still think the context should be exported since I suspect a lot of parameters are created just before they are sent.

brandur-stripe pushed a commit that referenced this issue Oct 19, 2017
Supports the `Context` struct [1] that came in with Go 1.7 on Stripe API
requests. This can be used to carry deadlines, cancelation signals, and
other request-scoped values across API boundaries and between processes.

Fixes #357.

[1] https://golang.org/pkg/context/
@brandur-stripe
Copy link
Contributor

Thanks for your patience everyone! We've released basic support for Context in 28.4.0.

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

No branches or pull requests

6 participants