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 wait-change API endpoint and client function #63
Changes from 3 commits
53afb74
87bea49
b101014
8133562
b51373d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,3 +157,31 @@ func (client *Client) Changes(opts *ChangesOptions) ([]*Change, error) { | |
|
||
return chgs, err | ||
} | ||
|
||
// WaitChangeOptions holds the options for the WaitChange call. | ||
type WaitChangeOptions struct { | ||
// If non-zero, wait at most this long before returning the current change | ||
// data. The timeout elapsing is not considered an error, so if a timeout | ||
// is specified, the caller should check Change.Ready to determine whether | ||
// the change is actually finished. | ||
Timeout time.Duration | ||
} | ||
|
||
// WaitChange waits for a given change to be finished (whether or not there | ||
// was an error, which is indicated by Change.Err being set). | ||
benhoyt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func (client *Client) WaitChange(id string, opts *WaitChangeOptions) (*Change, error) { | ||
var chgd changeAndData | ||
|
||
query := url.Values{} | ||
if opts != nil && opts.Timeout != 0 { | ||
query.Set("timeout", opts.Timeout.String()) | ||
} | ||
|
||
_, err := client.doSync("GET", "/v1/changes/"+id+"/wait", query, nil, nil, &chgd) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the timeout behavior of the underlying http library, and do we have to account for that and implement retries here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. I had observed it to be a very long timeout / no timeout in my manual testing, but just confirmed that now in the code -- we always create the |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
chgd.Change.data = chgd.Data | ||
return &chgd.Change, nil | ||
} |
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.
Timeout certainly sounds like an error, unless the operation did finish and there was a race condition. But otherwise, the intent of the operation of waiting for it to be finished did not succeed in intent, so an error seems appropriate.
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.
Yeah, Harry and I went back and forth on that and ended up that it shouldn't be an error, primarily because when Pebble returns an error it can't also return other data (the Change in this case), and I thought it might be useful to have the current state of the change at the time of the timeout.
However, on reflection it makes for a less error-prone API if it's just an error, and in the success case the change is always ready. If the caller really wants the current state of a change in the case of a timeout/error, they can always make an additional call to
client.Change()
to get the current status. However, it's unlikely you'll want to.In any case, I've used HTTP status code
504 Gateway Timeout
for this (along with a reasonable error message). It's not quite a perfect semantic match, but it seems close enough.