diff --git a/include/blob/blob_client.h b/include/blob/blob_client.h
index d53645f..73b6def 100644
--- a/include/blob/blob_client.h
+++ b/include/blob/blob_client.h
@@ -33,24 +33,31 @@ namespace azure { namespace storage_lite {
///
/// An existing object.
/// An int value indicates the maximum concurrency expected during execute requests against the service.
- blob_client(std::shared_ptr account, int max_concurrency)
- : m_account(account)
+ /// A string value with absolute path to CA bundle location.
+ blob_client(std::shared_ptr account, int max_concurrency, const std::string& ca_path = "")
+ : blob_client(account,
+ std::make_shared(std::make_shared(), std::make_shared()),
+ (ca_path.empty() ? std::make_shared(max_concurrency)
+ : std::make_shared(max_concurrency, ca_path)))
{
- m_context = std::make_shared(std::make_shared(), std::make_shared());
- m_client = std::make_shared(max_concurrency);
}
///
/// Initializes a new instance of the class.
///
/// An existing object.
+ /// A context of execution defining how to parser and the retry policy class.
/// An int value indicates the maximum concurrency expected during execute requests against the service.
/// A string value with absolute path to CA bundle location.
- blob_client(std::shared_ptr account, int max_concurrency, const std::string& ca_path)
- : m_account(account)
+ blob_client(std::shared_ptr account,
+ std::shared_ptr context,
+ int max_concurrency,
+ const std::string ca_path = "")
+ : blob_client(account,
+ context,
+ (ca_path.empty() ? std::make_shared(max_concurrency)
+ : std::make_shared(max_concurrency, ca_path)))
{
- m_context = std::make_shared(std::make_shared(), std::make_shared());
- m_client = std::make_shared(max_concurrency, ca_path);
}
///
@@ -321,6 +328,15 @@ namespace azure { namespace storage_lite {
AZURE_STORAGE_API std::future> start_copy(const std::string &sourceContainer, const std::string &sourceBlob, const std::string &destContainer, const std::string &destBlob);
private:
+ blob_client(std::shared_ptr account,
+ std::shared_ptr context,
+ std::shared_ptr client)
+ : m_client(client),
+ m_account(account),
+ m_context(context)
+ {
+ }
+
std::shared_ptr m_client;
std::shared_ptr m_account;
std::shared_ptr m_context;
diff --git a/include/constants.dat b/include/constants.dat
index 37fe556..38ce402 100644
--- a/include/constants.dat
+++ b/include/constants.dat
@@ -118,6 +118,9 @@ DAT(header_value_storage_version, "2018-11-09")
DAT(header_value_user_agent, "azure-storage-cpplite/0.1.0")
+DAT_TYPED(int, maximum_retries, 3)
+DAT_TYPED(int, base_timeout, 10)
+
DAT(date_format_rfc_1123, "%a, %d %b %Y %H:%M:%S GMT")
DAT(date_format_iso_8601, "%Y-%m-%dT%H:%M:%SZ")
diff --git a/include/constants.h b/include/constants.h
index ec139d8..8f1f212 100644
--- a/include/constants.h
+++ b/include/constants.h
@@ -5,7 +5,9 @@
namespace azure { namespace storage_lite { namespace constants {
#define DAT(x, y) extern AZURE_STORAGE_API const char *x; const int x ## _size{ sizeof(y) / sizeof(char) - 1 };
+#define DAT_TYPED(type, name, value) extern AZURE_STORAGE_API const type name;
#include "constants.dat"
#undef DAT
+#undef DAT_TYPED
-}}} // azure::storage_lite::constants
\ No newline at end of file
+}}} // azure::storage_lite::constants
diff --git a/include/get_container_property_request_base.h b/include/get_container_property_request_base.h
index bd12c4e..a0adbe3 100644
--- a/include/get_container_property_request_base.h
+++ b/include/get_container_property_request_base.h
@@ -33,7 +33,7 @@ namespace azure { namespace storage_lite {
m_valid = valid;
}
- bool valid()
+ bool valid() const
{
return m_valid;
}
diff --git a/include/retry.h b/include/retry.h
index 3831887..8dbfd52 100644
--- a/include/retry.h
+++ b/include/retry.h
@@ -6,6 +6,7 @@
#include "storage_EXPORTS.h"
+#include "constants.h"
#include "http_base.h"
#include "utility.h"
@@ -78,20 +79,23 @@ namespace azure { namespace storage_lite {
class retry_policy final : public retry_policy_base
{
public:
+
+ retry_policy(const int maximum_retries = azure::storage_lite::constants::maximum_retries,
+ const std::chrono::seconds base_timeout = std::chrono::seconds{azure::storage_lite::constants::base_timeout})
+ : m_maximum_retries(maximum_retries),
+ m_base_timeout(base_timeout)
+ {
+ }
+
retry_info evaluate(const retry_context &context) const override
{
- if (context.numbers() == 0)
- {
- return retry_info(true, std::chrono::seconds(0));
- }
- else if (context.numbers() < 26 && can_retry(context.result()))
+ if (context.numbers() >= m_maximum_retries ||
+ !can_retry(context.result()))
{
- double delay = (pow(1.2, context.numbers()-1)-1);
- delay = std::min(delay, 60.0); // Maximum backoff delay of 1 minute
- delay *= (((double)rand())/RAND_MAX)/2 + 0.75;
- return retry_info(true, std::chrono::seconds((int)delay));
+ return retry_info(false, std::chrono::seconds(0));
}
- return retry_info(false, std::chrono::seconds(0));
+
+ return retry_info(true, calculate_new_delay(context));
}
private:
@@ -99,6 +103,16 @@ namespace azure { namespace storage_lite {
{
return retryable(code);
}
+
+ std::chrono::seconds calculate_new_delay(const retry_context &context) const
+ {
+ // (1 << N) == 2^N
+ return ((context.numbers() == 0) ? std::chrono::seconds(0)
+ : (m_base_timeout * (1 << context.numbers())));
+ }
+
+ const int m_maximum_retries;
+ const std::chrono::seconds m_base_timeout;
};
}} // azure::storage_lite
diff --git a/include/utility.h b/include/utility.h
index 2b26fb1..7103d41 100644
--- a/include/utility.h
+++ b/include/utility.h
@@ -2,6 +2,8 @@
#include
#include
+#include