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

Exposing context.Context in exported API without requiring major version bump #267

Closed
22 tasks done
theckman opened this issue Feb 8, 2021 · 4 comments
Closed
22 tasks done
Milestone

Comments

@theckman
Copy link
Collaborator

theckman commented Feb 8, 2021

I'm raising this issue in anticipation of #266 being merged without many changes to the implementation.

Update: This proposal has been accepted and will be moving forward.

I'd like to provide consumers the ability to cancel outstanding requests using context.Context by creating methods within the package that take it as their first argument. We would not replace the current methods, but instead create a *WitContext() variant of each method so that you'd have GetUser() and GetUserWithContext(). We can accomplish this without code duplication, by having the non-context version call the *WithContext() variant and passing in a context.Background(). This should make the long-term maintenance minimal.

Progress Tracking

New Methods / Functions

For new additions / methods to the package, we SHOULD NOT have a *WithContext() variant and instead make the default implementation require a context.Context. For v2 I believe the *WithContext() variants should be dropped and the context.Context moved into the main method.

I think PR #260 is a good example of something we should update to have a context.Context as its first argument (no *WithContext() variant)

Why create such a large API to accomplish this?

Speaking intimately about the origins of this package, it was originally released as 1.0.0 versus a 0.x version which would have allowed us to more freely explore the API. Because we've already had a v1.0.0 and we use Go Modules, it would be a sizable amount of work for consumers to upgrade to v2+ (even if there aren't many changes they need to make to code).

As such, I think it's prudent for us to provide this functionality without breaking the API so we can better prepare for a 2.0.0 release that fixes any outstanding concerns we have with the API, so the cost that consumers need to pay is worth it.

Example Code

// GetUser gets details about an existing user. It's recommended to use
// GetUserWithContext instead.
func (c *Client) GetUser(id string, o GetUserOptions) (*User, error) {
	return c.GetUserWithContext(context.Background(), id, o)
}

// GetUserWithContext gets details about an existing user.
func (c *Client) GetUserWithContext(ctx context.Context, id string, o GetUserOptions) (*User, error) {
	v, err := query.Values(o)
	if err != nil {
		return nil, err
	}

	resp, err := c.get(ctx, "/users/"+id+"?"+v.Encode())
	return getUserFromResponse(c, resp, err)
}
Diff
diff --git a/user.go b/user.go
index d232b1c..daa999b 100644
--- a/user.go
+++ b/user.go
@@ -117,13 +117,19 @@ func (c *Client) DeleteUser(id string) error {
 	return err
 }
 
-// GetUser gets details about an existing user.
+// GetUser gets details about an existing user. It's recommended to use
+// GetUserWithContext instead.
 func (c *Client) GetUser(id string, o GetUserOptions) (*User, error) {
+	return c.GetUserWithContext(context.Background(), id, o)
+}
+
+// GetUserWithContext gets details about an existing user.
+func (c *Client) GetUserWithContext(ctx context.Context, id string, o GetUserOptions) (*User, error) {
 	v, err := query.Values(o)
 	if err != nil {
 		return nil, err
 	}
-	resp, err := c.get(context.TODO(), "/users/"+id+"?"+v.Encode())
+	resp, err := c.get(ctx, "/users/"+id+"?"+v.Encode())
 	return getUserFromResponse(c, resp, err)
 }
@theckman
Copy link
Collaborator Author

theckman commented Feb 9, 2021

@stmcallister happy to chat about this proposal over VC / voice if it's easier to have a high bandwidth conversation. If I take on this work I'll probably need to rely on you for reviews + merges, so I want to make sure we're aligned and I address any concerns you have before we go down the path (since it'll require a few PRs to accomplish).

@theckman
Copy link
Collaborator Author

Okay, I've spoke with Scott out of band about this and we're aligned on this being the right path forward to avoid introducing breaking changes. I'll start opening the PRs to update each file.

theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
theckman added a commit that referenced this issue Feb 26, 2021
This also updates the new methods to not return the `*http.Response`, as it
doesn't seem needed.

Updates #267
theckman added a commit that referenced this issue Feb 27, 2021
theckman added a commit that referenced this issue Feb 27, 2021
This also updates the new methods to not return the `*http.Response`, as it
doesn't seem needed.

Updates #267
theckman added a commit that referenced this issue Feb 27, 2021
This also updates the new methods to not return the `*http.Response`, as it
doesn't seem needed.

Updates #267
theckman added a commit that referenced this issue Feb 27, 2021
theckman added a commit that referenced this issue Feb 27, 2021
theckman added a commit that referenced this issue Feb 27, 2021
theckman added a commit that referenced this issue Mar 5, 2021
theckman added a commit that referenced this issue Mar 6, 2021
While adding `context.Context` support to the `schedule.go` file, I found a
`nil` map write in PreviewSchedule(). This makes me believe this method may be
unused, otherwise I would expect a panic report.

Updates #267
theckman added a commit that referenced this issue Mar 6, 2021
theckman added a commit that referenced this issue Mar 6, 2021
theckman added a commit that referenced this issue Mar 6, 2021
@theckman
Copy link
Collaborator Author

theckman commented Mar 6, 2021

@stmcallister all PRs have been opened for this issue, ready for review!

theckman added a commit that referenced this issue Mar 8, 2021
@theckman
Copy link
Collaborator Author

All PRs were merged; this is done! 🎉

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

No branches or pull requests

2 participants