azure-core
context.hpp
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // SPDX-License-Identifier: MIT
3 
9 #pragma once
10 
12 #include "azure/core/datetime.hpp"
14 #include "azure/core/rtti.hpp"
15 #include <atomic>
16 #include <chrono>
17 #include <memory>
18 #include <stdexcept>
19 #include <string>
20 #include <type_traits>
21 
22 // Forward declare TracerProvider to resolve an include file dependency ordering problem.
23 namespace Azure { namespace Core { namespace Tracing {
24  class TracerProvider;
25 }}} // namespace Azure::Core::Tracing
26 
27 namespace Azure { namespace Core {
28 
32  class OperationCancelledException final : public std::runtime_error {
33  public:
39  explicit OperationCancelledException(std::string const& what) : std::runtime_error(what) {}
40  };
41 
45  class Context final {
46  public:
50  class Key final {
51  Key const* m_uniqueAddress;
52 
53  public:
58  Key() : m_uniqueAddress(this) {}
59 
65  bool operator==(Key const& other) const
66  {
67  return this->m_uniqueAddress == other.m_uniqueAddress;
68  }
69 
75  bool operator!=(Key const& other) const { return !(*this == other); }
76  };
77 
78  private:
79  struct ContextSharedState final
80  {
81  std::shared_ptr<ContextSharedState> Parent;
82  std::atomic<DateTime::rep> Deadline;
83  std::shared_ptr<Azure::Core::Tracing::TracerProvider> TraceProvider;
84  Context::Key Key;
85  std::shared_ptr<void> Value;
86 #if defined(AZ_CORE_RTTI)
87  const std::type_info& ValueType;
88 #endif
89  static constexpr DateTime::rep ToDateTimeRepresentation(DateTime const& dateTime)
90  {
91  return dateTime.time_since_epoch().count();
92  }
93 
94  static constexpr DateTime FromDateTimeRepresentation(DateTime::rep dtRepresentation)
95  {
96  return DateTime(DateTime::time_point(DateTime::duration(dtRepresentation)));
97  }
98 
99  explicit ContextSharedState()
100  : Deadline(ToDateTimeRepresentation((DateTime::max)())), Value(nullptr)
101 #if defined(AZ_CORE_RTTI)
102  ,
103  ValueType(typeid(std::nullptr_t))
104 #endif
105  {
106  }
107 
108  explicit ContextSharedState(
109  const std::shared_ptr<ContextSharedState>& parent,
110  DateTime const& deadline)
111  : Parent(parent), Deadline(ToDateTimeRepresentation(deadline)), Value(nullptr)
112 #if defined(AZ_CORE_RTTI)
113  ,
114  ValueType(typeid(std::nullptr_t))
115 #endif
116  {
117  }
118 
119  template <class T>
120  explicit ContextSharedState(
121  const std::shared_ptr<ContextSharedState>& parent,
122  DateTime const& deadline,
123  Context::Key const& key,
124  T value) // NOTE, should this be T&&
125  : Parent(parent), Deadline(ToDateTimeRepresentation(deadline)), Key(key),
126  Value(std::make_shared<T>(std::move(value)))
127 #if defined(AZ_CORE_RTTI)
128  ,
129  ValueType(typeid(T))
130 #endif
131  {
132  }
133  };
134 
135  std::shared_ptr<ContextSharedState> m_contextSharedState;
136 
137  explicit Context(std::shared_ptr<ContextSharedState> impl)
138  : m_contextSharedState(std::move(impl))
139  {
140  }
141 
142  public:
147  Context() : m_contextSharedState(std::make_shared<ContextSharedState>()) {}
148 
156  Context& operator=(const Context& other) = default;
157 
165  Context WithDeadline(DateTime const& deadline) const
166  {
167  return Context{std::make_shared<ContextSharedState>(m_contextSharedState, deadline)};
168  }
169 
179  template <class T> Context WithValue(Key const& key, T&& value) const
180  {
181  return Context{std::make_shared<ContextSharedState>(
182  m_contextSharedState, (DateTime::max)(), key, std::forward<T>(value))};
183  }
184 
193  DateTime GetDeadline() const;
194 
209  template <class T> bool TryGetValue(Key const& key, T& outputValue) const
210  {
211  for (auto ptr = m_contextSharedState; ptr; ptr = ptr->Parent)
212  {
213  if (ptr->Key == key)
214  {
215 #if defined(AZ_CORE_RTTI)
216  AZURE_ASSERT_MSG(
217  typeid(T) == ptr->ValueType, "Type mismatch for Context::TryGetValue().");
218 #endif
219 
220  outputValue = *reinterpret_cast<const T*>(ptr->Value.get());
221  return true;
222  }
223  }
224  return false;
225  }
226 
231  void Cancel()
232  {
233  m_contextSharedState->Deadline
234  = ContextSharedState::ToDateTimeRepresentation((DateTime::min)());
235  }
236 
241  bool IsCancelled() const { return GetDeadline() < std::chrono::system_clock::now(); }
242 
248  void ThrowIfCancelled() const
249  {
250  if (IsCancelled())
251  {
252  throw OperationCancelledException("Request was cancelled by context.");
253  }
254  }
255 
259  std::shared_ptr<Tracing::TracerProvider> GetTracerProvider()
260  {
261  return m_contextSharedState->TraceProvider;
262  }
263 
267  void SetTracerProvider(std::shared_ptr<Tracing::TracerProvider> tracerProvider)
268  {
269  m_contextSharedState->TraceProvider = tracerProvider;
270  }
271 
277  };
278 }} // namespace Azure::Core
Azure::Core::Context::GetTracerProvider
std::shared_ptr< Tracing::TracerProvider > GetTracerProvider()
Returns the tracer provider for the current context.
Definition: context.hpp:259
Azure::Core::Context::ThrowIfCancelled
void ThrowIfCancelled() const
Checks if the context is cancelled.
Definition: context.hpp:248
AZ_CORE_DLLEXPORT
#define AZ_CORE_DLLEXPORT
Applies DLL export attribute, when applicable.
Definition: dll_import_export.hpp:93
Azure::Core::OperationCancelledException::OperationCancelledException
OperationCancelledException(std::string const &what)
Constructs an OperationCancelledException with message string as the description.
Definition: context.hpp:39
datetime.hpp
Support for date and time standardized string formats.
Azure::Core::Context::IsCancelled
bool IsCancelled() const
Checks if the context is cancelled.
Definition: context.hpp:241
Azure::Core::Context::GetDeadline
DateTime GetDeadline() const
Gets the deadline for this context or the branch of contexts this context belongs to.
Definition: context.cpp:10
Azure::Core::OperationCancelledException
An exception thrown when an operation is cancelled.
Definition: context.hpp:32
rtti.hpp
Run-time type info enable or disable.
Azure::Core::Context::WithValue
Context WithValue(Key const &key, T &&value) const
Creates a context without a deadline, but with key and value associated with it.
Definition: context.hpp:179
Azure::Core::Context::SetTracerProvider
void SetTracerProvider(std::shared_ptr< Tracing::TracerProvider > tracerProvider)
Sets the tracer provider for the current context.
Definition: context.hpp:267
Azure::Core::Context::WithDeadline
Context WithDeadline(DateTime const &deadline) const
Creates a context with a deadline.
Definition: context.hpp:165
Azure
Azure SDK abstractions.
Definition: azure_assert.hpp:55
Azure::Core::Context::TryGetValue
bool TryGetValue(Key const &key, T &outputValue) const
Gets the value associated with a key parameter within this context or the branch of contexts this con...
Definition: context.hpp:209
Azure::Core::Context::Cancel
void Cancel()
Cancels the context.
Definition: context.hpp:231
dll_import_export.hpp
DLL export macro.
azure_assert.hpp
Provide assert macros to use with pre-conditions.
Azure::DateTime
Manages date and time in standardized string formats.
Definition: datetime.hpp:54
Azure::Core::Context::Key::operator!=
bool operator!=(Key const &other) const
Compares with other Key for equality.
Definition: context.hpp:75
Azure::Core::Context::operator=
Context & operator=(const Context &other)=default
Assigns Context to another Context instance.
Azure::Core::Context::Key::operator==
bool operator==(Key const &other) const
Compares with other Key for equality.
Definition: context.hpp:65
Azure::Core::Context::Context
Context()
Constructs a new context with no deadline, and no value associated.
Definition: context.hpp:147
Azure::Core::Context
A context is a node within a tree that represents deadlines and key/value pairs.
Definition: context.hpp:45
Azure::Core::Context::Key
A key used to store and retrieve data in an Azure::Core::Context object.
Definition: context.hpp:50
Azure::Core::Context::ApplicationContext
static AZ_CORE_DLLEXPORT Context ApplicationContext
The application context (root).
Definition: context.hpp:276
Azure::Core::Context::Key::Key
Key()
Constructs a default instance of Key.
Definition: context.hpp:58