From 1d1fe4da7e7dda6448e86fca3e1d94bb264fca68 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Thu, 9 Dec 2021 15:26:05 -0500 Subject: [PATCH] feat(storage): configurable retries for uploads Depends on merge and release of googleapis/google-api-go-client#1324 --- storage/writer.go | 19 +++++++++++++++++++ storage/writer_test.go | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/storage/writer.go b/storage/writer.go index ec55e4a3ba4..dd468c5bf9e 100644 --- a/storage/writer.go +++ b/storage/writer.go @@ -172,6 +172,25 @@ func (w *Writer) open() error { // call to set up the upload as well as calls to upload individual chunks // for a resumable upload (as long as the chunk size is non-zero). Hence // there is no need to add retries here. + + // Retry only when the operation is idempotent or the retry policy is RetryAlways. + var isIdempotent bool + if w.o.conds != nil && (w.o.conds.GenerationMatch >= 0 || w.o.conds.DoesNotExist == true) { + isIdempotent = true + } + var useRetry bool + if (w.o.retry == nil || w.o.retry.policy == RetryIdempotent) && isIdempotent { + useRetry = true + } else if w.o.retry != nil && w.o.retry.policy == RetryAlways { + useRetry = true + } + if useRetry { + if w.o.retry != nil { + call.WithRetry(w.o.retry.backoff, w.o.retry.shouldRetry) + } else { + call.WithRetry(nil, nil) + } + } resp, err = call.Do() } if err != nil { diff --git a/storage/writer_test.go b/storage/writer_test.go index 7ac9b7ef509..2537da9a633 100644 --- a/storage/writer_test.go +++ b/storage/writer_test.go @@ -36,7 +36,7 @@ func TestErrorOnObjectsInsertCall(t *testing.T) { doWrite := func(mt *mockTransport) *Writer { client := mockClient(t, mt) - wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) + wc := client.Bucket("bucketname").Object("filename1").If(Conditions{DoesNotExist: true}).NewWriter(ctx) wc.ContentType = "text/plain" // We can't check that the Write fails, since it depends on the write to the