aboutsummaryrefslogtreecommitdiff
path: root/vendor/cloud.google.com/go/storage/writer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/cloud.google.com/go/storage/writer.go')
-rw-r--r--vendor/cloud.google.com/go/storage/writer.go39
1 files changed, 31 insertions, 8 deletions
diff --git a/vendor/cloud.google.com/go/storage/writer.go b/vendor/cloud.google.com/go/storage/writer.go
index 28eb74a..93597c8 100644
--- a/vendor/cloud.google.com/go/storage/writer.go
+++ b/vendor/cloud.google.com/go/storage/writer.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
+// Copyright 2014 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import (
"errors"
"fmt"
"io"
+ "sync"
"unicode/utf8"
"golang.org/x/net/context"
@@ -47,8 +48,11 @@ type Writer struct {
// to the nearest multiple of 256K. If zero, chunking will be disabled and
// the object will be uploaded in a single request.
//
- // ChunkSize will default to a reasonable value. Any custom configuration
- // must be done before the first Write call.
+ // ChunkSize will default to a reasonable value. If you perform many concurrent
+ // writes of small objects, you may wish set ChunkSize to a value that matches
+ // your objects' sizes to avoid consuming large amounts of memory.
+ //
+ // ChunkSize must be set before the first Write call.
ChunkSize int
// ProgressFunc can be used to monitor the progress of a large write.
@@ -68,8 +72,10 @@ type Writer struct {
pw *io.PipeWriter
donec chan struct{} // closed after err and obj are set.
- err error
obj *ObjectAttrs
+
+ mu sync.Mutex
+ err error
}
func (w *Writer) open() error {
@@ -82,6 +88,9 @@ func (w *Writer) open() error {
if !utf8.ValidString(attrs.Name) {
return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name)
}
+ if attrs.KMSKeyName != "" && w.o.encryptionKey != nil {
+ return errors.New("storage: cannot use KMSKeyName with a customer-supplied encryption key")
+ }
pr, pw := io.Pipe()
w.pw = pw
w.opened = true
@@ -113,9 +122,14 @@ func (w *Writer) open() error {
if w.ProgressFunc != nil {
call.ProgressUpdater(func(n, _ int64) { w.ProgressFunc(n) })
}
+ if attrs.KMSKeyName != "" {
+ call.KmsKeyName(attrs.KMSKeyName)
+ }
if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil {
+ w.mu.Lock()
w.err = err
- pr.CloseWithError(w.err)
+ w.mu.Unlock()
+ pr.CloseWithError(err)
return
}
var resp *raw.Object
@@ -142,8 +156,10 @@ func (w *Writer) open() error {
}
}
if err != nil {
+ w.mu.Lock()
w.err = err
- pr.CloseWithError(w.err)
+ w.mu.Unlock()
+ pr.CloseWithError(err)
return
}
w.obj = newObject(resp)
@@ -158,8 +174,11 @@ func (w *Writer) open() error {
// use the error returned from Writer.Close to determine if
// the upload was successful.
func (w *Writer) Write(p []byte) (n int, err error) {
- if w.err != nil {
- return 0, w.err
+ w.mu.Lock()
+ werr := w.err
+ w.mu.Unlock()
+ if werr != nil {
+ return 0, werr
}
if !w.opened {
if err := w.open(); err != nil {
@@ -182,11 +201,15 @@ func (w *Writer) Close() error {
return err
}
<-w.donec
+ w.mu.Lock()
+ defer w.mu.Unlock()
return w.err
}
// CloseWithError aborts the write operation with the provided error.
// CloseWithError always returns nil.
+//
+// Deprecated: cancel the context passed to NewWriter instead.
func (w *Writer) CloseWithError(err error) error {
if !w.opened {
return nil