Skip to content

Commit d3a252d

Browse files
authored
Use the same client-request-id for retry requests (Azure#5182)
1 parent 71cee91 commit d3a252d

File tree

6 files changed

+51
-16
lines changed

6 files changed

+51
-16
lines changed

sdk/storage/azure-storage-blobs/src/blob_client.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,15 @@ namespace Azure { namespace Storage { namespace Blobs {
204204
{
205205
// In case network failure during reading the body
206206
const Azure::ETag eTag = downloadResponse.Value.Details.ETag;
207-
208-
auto retryFunction
209-
= [this, options, eTag](int64_t retryOffset, const Azure::Core::Context& context)
210-
-> std::unique_ptr<Azure::Core::IO::BodyStream> {
207+
const std::string client_request_id
208+
= downloadResponse.RawResponse->GetHeaders().find(_internal::HttpHeaderClientRequestId)
209+
== downloadResponse.RawResponse->GetHeaders().end()
210+
? std::string()
211+
: downloadResponse.RawResponse->GetHeaders().at(_internal::HttpHeaderClientRequestId);
212+
auto retryFunction =
213+
[this, options, eTag, client_request_id](
214+
int64_t retryOffset,
215+
const Azure::Core::Context& context) -> std::unique_ptr<Azure::Core::IO::BodyStream> {
211216
DownloadBlobOptions newOptions = options;
212217
newOptions.Range = Core::Http::HttpRange();
213218
newOptions.Range.Value().Offset
@@ -217,7 +222,11 @@ namespace Azure { namespace Storage { namespace Blobs {
217222
newOptions.Range.Value().Length = options.Range.Value().Length.Value() - retryOffset;
218223
}
219224
newOptions.AccessConditions.IfMatch = eTag;
220-
return std::move(Download(newOptions, context).Value.BodyStream);
225+
return std::move(
226+
Download(
227+
newOptions,
228+
context.WithValue(_internal::ReliableStreamClientRequestIdKey, client_request_id))
229+
.Value.BodyStream);
221230
};
222231

223232
_internal::ReliableStreamOptions reliableStreamOptions;

sdk/storage/azure-storage-common/inc/azure/storage/common/internal/constants.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ namespace Azure { namespace Storage { namespace _internal {
1010
constexpr static const char* QueueServicePackageName = "storage-queues";
1111
constexpr static const char* HttpQuerySnapshot = "snapshot";
1212
constexpr static const char* HttpQueryVersionId = "versionid";
13+
constexpr static const char* HttpQueryTimeout = "timeout";
1314
constexpr static const char* StorageScope = "https://storage.azure.com/.default";
1415
constexpr static const char* StorageDefaultAudience = "https://storage.azure.com";
1516
constexpr static const char* HttpHeaderDate = "date";
17+
constexpr static const char* HttpHeaderXMsDate = "x-ms-date";
1618
constexpr static const char* HttpHeaderXMsVersion = "x-ms-version";
1719
constexpr static const char* HttpHeaderRequestId = "x-ms-request-id";
1820
constexpr static const char* HttpHeaderClientRequestId = "x-ms-client-request-id";

sdk/storage/azure-storage-common/inc/azure/storage/common/internal/reliable_stream.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
#pragma once
5+
6+
#include "azure/storage/common/dll_import_export.hpp"
7+
48
#include <azure/core/context.hpp>
59
#include <azure/core/io/body_stream.hpp>
610

@@ -10,6 +14,9 @@
1014

1115
namespace Azure { namespace Storage { namespace _internal {
1216

17+
AZ_STORAGE_COMMON_DLLEXPORT extern const Azure::Core::Context::Key
18+
ReliableStreamClientRequestIdKey;
19+
1320
// Options used by reliable stream
1421
struct ReliableStreamOptions final
1522
{

sdk/storage/azure-storage-common/src/reliable_stream.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace Azure { namespace Storage {
2020
} // namespace _detail
2121

2222
namespace _internal {
23+
Azure::Core::Context::Key const ReliableStreamClientRequestIdKey;
2324

2425
size_t ReliableStream::OnRead(uint8_t* buffer, size_t count, Context const& context)
2526
{

sdk/storage/azure-storage-common/src/storage_per_retry_policy.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
#include "azure/storage/common/internal/storage_per_retry_policy.hpp"
55

6+
#include "azure/storage/common/internal/constants.hpp"
7+
#include "azure/storage/common/internal/reliable_stream.hpp"
8+
69
#include <azure/core/datetime.hpp>
710
#include <azure/core/platform.hpp>
811

@@ -16,9 +19,6 @@ namespace Azure { namespace Storage { namespace _internal {
1619
Core::Http::Policies::NextHttpPolicy nextPolicy,
1720
Core::Context const& context) const
1821
{
19-
const char* HttpHeaderDate = "Date";
20-
const char* HttpHeaderXMsDate = "x-ms-date";
21-
2222
const auto& headers = request.GetHeaders();
2323
if (headers.find(HttpHeaderDate) == headers.end())
2424
{
@@ -29,11 +29,10 @@ namespace Azure { namespace Storage { namespace _internal {
2929
.ToString(Azure::DateTime::DateFormat::Rfc1123));
3030
}
3131

32-
const char* HttpHeaderTimeout = "timeout";
3332
auto cancelTimepoint = context.GetDeadline();
3433
if (cancelTimepoint == Azure::DateTime::max())
3534
{
36-
request.GetUrl().RemoveQueryParameter(HttpHeaderTimeout);
35+
request.GetUrl().RemoveQueryParameter(HttpQueryTimeout);
3736
}
3837
else
3938
{
@@ -43,8 +42,18 @@ namespace Azure { namespace Storage { namespace _internal {
4342
.count()
4443
: -1;
4544
request.GetUrl().AppendQueryParameter(
46-
HttpHeaderTimeout, std::to_string(std::max(numSeconds, int64_t(1))));
45+
HttpQueryTimeout, std::to_string(std::max(numSeconds, int64_t(1))));
46+
}
47+
48+
std::string client_request_id;
49+
if (context.TryGetValue(ReliableStreamClientRequestIdKey, client_request_id))
50+
{
51+
if (!client_request_id.empty())
52+
{
53+
request.SetHeader(HttpHeaderClientRequestId, client_request_id);
54+
}
4755
}
56+
4857
return nextPolicy.Send(request, context);
4958
}
5059

sdk/storage/azure-storage-files-shares/src/share_file_client.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
305305
{
306306
// In case network failure during reading the body
307307
auto eTag = downloadResponse.Value.Details.ETag;
308-
309-
auto retryFunction
310-
= [this, options, eTag](int64_t retryOffset, const Azure::Core::Context& context)
311-
-> std::unique_ptr<Azure::Core::IO::BodyStream> {
308+
const std::string client_request_id
309+
= downloadResponse.RawResponse->GetHeaders().find(_internal::HttpHeaderClientRequestId)
310+
== downloadResponse.RawResponse->GetHeaders().end()
311+
? std::string()
312+
: downloadResponse.RawResponse->GetHeaders().at(_internal::HttpHeaderClientRequestId);
313+
auto retryFunction =
314+
[this, options, eTag, client_request_id](
315+
int64_t retryOffset,
316+
const Azure::Core::Context& context) -> std::unique_ptr<Azure::Core::IO::BodyStream> {
312317
DownloadFileOptions newOptions = options;
313318
newOptions.Range = Core::Http::HttpRange();
314319
newOptions.Range.Value().Offset
@@ -318,7 +323,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
318323
newOptions.Range.Value().Length = options.Range.Value().Length.Value() - retryOffset;
319324
}
320325

321-
auto newResponse = Download(newOptions, context);
326+
auto newResponse = Download(
327+
newOptions,
328+
context.WithValue(_internal::ReliableStreamClientRequestIdKey, client_request_id));
322329
if (eTag != newResponse.Value.Details.ETag)
323330
{
324331
throw Azure::Core::RequestFailedException("File was modified in the middle of download.");

0 commit comments

Comments
 (0)