From 9c072232ddd5017b991536fbd73be841ffff02c7 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Fri, 8 Sep 2023 12:22:07 +0000 Subject: [PATCH 1/2] docs(storage): more on InsertObject vs. WriteObject Show that both `InsertObject()` and `WriteObject()` can be used to upload data from memory. At least one customer missed the existence of `InsertObject()` because they thought the example showed **all** the ways. Fixed the links showing the tradeoffs between single-shot and resumable-uploads. Be more explicit about what upload type does `InsertObject()` use. --- google/cloud/storage/client.h | 20 ++++++++++++++----- .../examples/storage_object_samples.cc | 15 +++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/google/cloud/storage/client.h b/google/cloud/storage/client.h index 32d03ea62a617..de5566233f765 100644 --- a/google/cloud/storage/client.h +++ b/google/cloud/storage/client.h @@ -854,6 +854,12 @@ class Client { /** * Creates an object given its name and contents. * + * If you need to perform larger uploads or uploads where the data is not + * contiguous in memory use `WriteObject()`. This function always performs a + * single-shot upload, while `WriteObject()` always uses resumable uploads. + * The [service documentation] has recommendations on the upload size vs. + * single-shot or resumable uploads. + * * @param bucket_name the name of the bucket that will contain the object. * @param object_name the name of the object to be created. * @param contents the contents (media) for the new object. @@ -874,6 +880,9 @@ class Client { * * @par Example * @snippet storage_object_samples.cc insert object multipart + * + * [service documentation]: + * https://cloud.google.com/storage/docs/uploads-downloads#size */ template StatusOr InsertObject(std::string const& bucket_name, @@ -1135,6 +1144,10 @@ class Client { * can use either the regular `operator<<()`, or `std::ostream::write()` to * upload data. * + * For small uploads where all the data is contiguous in memory we recommend + * using `InsertObject()`. The [service documentation] has specific + * recommendations on object sizes and upload types. + * * This function always uses [resumable uploads][resumable-link]. The * application can provide a `#RestoreResumableUploadSession()` option to * resume a previously created upload. The returned object has accessors to @@ -1145,9 +1158,6 @@ class Client { * application's responsibility to query the next expected byte and send * the remaining data without gaps or duplications. * - * For small uploads we recommend using `InsertObject`, consult - * [the documentation][how-to-upload-link] for details. - * * If the application does not provide a `#RestoreResumableUploadSession()` * option, or it provides the `#NewResumableUploadSession()` option then a new * resumable upload session is created. @@ -1186,8 +1196,8 @@ class Client { * resumable uploads. * * [resumable-link]: https://cloud.google.com/storage/docs/resumable-uploads - * [how-to-upload-link]: - * https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload + * [service documentation]: + * https://cloud.google.com/storage/docs/uploads-downloads#size */ template ObjectWriteStream WriteObject(std::string const& bucket_name, diff --git a/google/cloud/storage/examples/storage_object_samples.cc b/google/cloud/storage/examples/storage_object_samples.cc index aa278d995ae8d..a1342966b4c8f 100644 --- a/google/cloud/storage/examples/storage_object_samples.cc +++ b/google/cloud/storage/examples/storage_object_samples.cc @@ -375,15 +375,24 @@ void WriteObjectFromMemory(google::cloud::storage::Client client, [](gcs::Client client, std::string const& bucket_name, std::string const& object_name) { std::string const text = "Lorem ipsum dolor sit amet"; + // For small uploads where the data is contiguous in memory use + // `InsertObject()`. For more specific size recommendations see + // https://cloud.google.com/storage/docs/uploads-downloads#size + auto metadata = client.InsertObject(bucket_name, object_name, text); + if (!metadata) throw std::move(metadata).status(); + std::cout << "Successfully wrote to object " << metadata->name() + << " its size is: " << metadata->size() << "\n"; + + // For larger uploads, or uploads where the data is not contiguous in + // memory, use `WriteObject()`. Consider using `std::ostream::write()` for + // best performance. std::vector v(100, text); gcs::ObjectWriteStream stream = client.WriteObject(bucket_name, object_name); - std::copy(v.begin(), v.end(), std::ostream_iterator(stream)); - stream.Close(); - StatusOr metadata = std::move(stream).metadata(); + metadata = std::move(stream).metadata(); if (!metadata) throw std::move(metadata).status(); std::cout << "Successfully wrote to object " << metadata->name() << " its size is: " << metadata->size() From 7581a8a7e5185f3957e6f55f76aa07ed73edfb1a Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Fri, 8 Sep 2023 13:29:08 +0000 Subject: [PATCH 2/2] Address review comments --- google/cloud/storage/client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/storage/client.h b/google/cloud/storage/client.h index de5566233f765..a8d980d79b9dc 100644 --- a/google/cloud/storage/client.h +++ b/google/cloud/storage/client.h @@ -855,7 +855,7 @@ class Client { * Creates an object given its name and contents. * * If you need to perform larger uploads or uploads where the data is not - * contiguous in memory use `WriteObject()`. This function always performs a + * contiguous in memory, use `WriteObject()`. This function always performs a * single-shot upload, while `WriteObject()` always uses resumable uploads. * The [service documentation] has recommendations on the upload size vs. * single-shot or resumable uploads.