X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e028e5daadb83ef695b7e0b1ef6bd45eef4cfc29..bc816b50fc16182fef2f5d17ffd61578432e83c3:/services/keepstore/azure_blob_volume.go diff --git a/services/keepstore/azure_blob_volume.go b/services/keepstore/azure_blob_volume.go index 7545e52e86..657c3151ca 100644 --- a/services/keepstore/azure_blob_volume.go +++ b/services/keepstore/azure_blob_volume.go @@ -122,7 +122,7 @@ func (v *AzureBlobVolume) Get(loc string) ([]byte, error) { var deadline time.Time haveDeadline := false buf, err := v.get(loc) - for err == nil && len(buf) == 0 && loc[:32] != "d41d8cd98f00b204e9800998ecf8427e" { + for err == nil && len(buf) == 0 && loc != "d41d8cd98f00b204e9800998ecf8427e" { // Seeing a brand new empty block probably means we're // in a race with CreateBlob, which under the hood // (apparently) does "CreateEmpty" and "CommitData" @@ -134,38 +134,34 @@ func (v *AzureBlobVolume) Get(loc string) ([]byte, error) { break } deadline = t.Add(azureWriteRaceInterval) + if time.Now().After(deadline) { + break + } + log.Printf("Race? Block %s is 0 bytes, %s old. Polling until %s", loc, time.Since(t), deadline) haveDeadline = true - } - if time.Now().After(deadline) { + } else if time.Now().After(deadline) { break } bufs.Put(buf) time.Sleep(azureWriteRacePollTime) buf, err = v.get(loc) } + if haveDeadline { + log.Printf("Race ended with len(buf)==%d", len(buf)) + } return buf, err } func (v *AzureBlobVolume) get(loc string) ([]byte, error) { rdr, err := v.bsClient.GetBlob(v.containerName, loc) if err != nil { - if strings.Contains(err.Error(), "404 Not Found") { - // "storage: service returned without a response body (404 Not Found)" - return nil, os.ErrNotExist - } - return nil, err - } - switch err := err.(type) { - case nil: - default: - log.Printf("ERROR IN Get(): %T %#v", err, err) - return nil, err + return nil, v.translateError(err) } defer rdr.Close() buf := bufs.Get(BlockSize) n, err := io.ReadFull(rdr, buf) switch err { - case io.EOF, io.ErrUnexpectedEOF: + case nil, io.EOF, io.ErrUnexpectedEOF: return buf[:n], nil default: bufs.Put(buf) @@ -176,7 +172,7 @@ func (v *AzureBlobVolume) get(loc string) ([]byte, error) { func (v *AzureBlobVolume) Compare(loc string, expect []byte) error { rdr, err := v.bsClient.GetBlob(v.containerName, loc) if err != nil { - return err + return v.translateError(err) } defer rdr.Close() return compareReaderWithBuf(rdr, expect, loc[:32]) @@ -279,3 +275,17 @@ func (v *AzureBlobVolume) Writable() bool { func (v *AzureBlobVolume) Replication() int { return v.replication } + +// If possible, translate an Azure SDK error to a recognizable error +// like os.ErrNotExist. +func (v *AzureBlobVolume) translateError(err error) error { + switch { + case err == nil: + return err + case strings.Contains(err.Error(), "404 Not Found"): + // "storage: service returned without a response body (404 Not Found)" + return os.ErrNotExist + default: + return err + } +}