Skip to content

Commit

Permalink
poller: retry LRO polling if 404 response received, closes #740
Browse files Browse the repository at this point in the history
  • Loading branch information
manicminer committed Mar 1, 2024
1 parent ddac485 commit 502e9eb
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
4 changes: 2 additions & 2 deletions sdk/client/pollers/poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (p *Poller) PollUntilDone(ctx context.Context) error {
go func() {
connectionDropCounter := 0
retryDuration := p.initialDelayDuration
for true {
for {
// determine the next retry duration / how long to poll for
if p.latestResponse != nil {
retryDuration = p.latestResponse.PollInterval
Expand All @@ -129,7 +129,7 @@ func (p *Poller) PollUntilDone(ctx context.Context) error {
// connection drops can either have no response/error (where we have no context)
connectionHasBeenDropped = true
} else if _, ok := p.latestError.(PollingDroppedConnectionError); ok {
// or have an error with more details (e.g. server not found, connection reset etc)
// or have an error with more details (e.g. server not found, connection reset etc.)
connectionHasBeenDropped = true
}
if connectionHasBeenDropped {
Expand Down
14 changes: 11 additions & 3 deletions sdk/client/resourcemanager/poller_lro.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import (
"strings"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/sdk/client"
"github.com/hashicorp/go-azure-sdk/sdk/client/pollers"
"github.com/hashicorp/go-azure-sdk/sdk/odata"
)

var _ pollers.PollerType = &longRunningOperationPoller{}
Expand Down Expand Up @@ -77,6 +79,14 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers.
return nil, fmt.Errorf("internal error: cannot poll without a pollingUrl")
}

// Retry the polling operation if a 404 was returned
retryOn404 := func(resp *http.Response, _ *odata.OData) (bool, error) {
if resp != nil && response.WasStatusCode(resp, http.StatusNotFound) {
return true, nil
}
return false, nil
}

reqOpts := client.RequestOptions{
ContentType: "application/json; charset=utf-8",
ExpectedStatusCodes: []int{
Expand All @@ -88,6 +98,7 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers.
HttpMethod: http.MethodGet,
OptionsObject: nil,
Path: p.pollingUrl.Path,
RetryFunc: client.RequestRetryAny(append(defaultRetryFunctions, retryOn404)...),
}

// TODO: port over the `api-version` header
Expand All @@ -98,9 +109,6 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers.
}
req.URL.RawQuery = p.pollingUrl.RawQuery

// Custom RetryFunc to inspect the operation payload and check the status
req.RetryFunc = client.RequestRetryAny(defaultRetryFunctions...)

result = &pollers.PollResult{
PollInterval: p.initialRetryDuration,
}
Expand Down

0 comments on commit 502e9eb

Please sign in to comment.