C++ Server-Side SDK
LaunchDarkly SDK
client_impl.hpp
1 #pragma once
2 
3 #include "data_components/status_notifications/data_source_status_manager.hpp"
4 #include "data_interfaces/system/idata_system.hpp"
5 #include "evaluation/evaluator.hpp"
6 #include "events/event_scope.hpp"
7 #include "hooks/hook_executor.hpp"
8 
9 #include <launchdarkly/config/client.hpp>
10 #include <launchdarkly/context.hpp>
11 #include <launchdarkly/data/evaluation_detail.hpp>
12 #include <launchdarkly/error.hpp>
13 #include <launchdarkly/events/event_processor_interface.hpp>
14 #include <launchdarkly/logging/logger.hpp>
15 #include <launchdarkly/server_side/client.hpp>
16 #include <launchdarkly/value.hpp>
17 
18 #include <boost/asio/executor_work_guard.hpp>
19 #include <boost/asio/io_context.hpp>
20 
21 #include <tl/expected.hpp>
22 
23 #include <condition_variable>
24 #include <cstdint>
25 #include <memory>
26 #include <optional>
27 #include <shared_mutex>
28 #include <thread>
29 #include <tuple>
30 
31 namespace launchdarkly::server_side {
32 
33 class ClientImpl : public IClient {
34  public:
35  ClientImpl(Config config, std::string const& version);
36 
37  ClientImpl(ClientImpl&&) = delete;
38  ClientImpl(ClientImpl const&) = delete;
39  ClientImpl& operator=(ClientImpl) = delete;
40  ClientImpl& operator=(ClientImpl&& other) = delete;
41 
42  bool Initialized() const override;
43 
44  using FlagKey = std::string;
45  [[nodiscard]] class AllFlagsState AllFlagsState(
46  Context const& context,
47  AllFlagsState::Options options =
49 
50  void Track(Context const& ctx,
51  std::string event_name,
52  Value data,
53  double metric_value) override;
54 
55  void Track(Context const& ctx,
56  std::string event_name,
57  Value data,
58  double metric_value,
59  hooks::HookContext const& hook_context) override;
60 
61  void Track(Context const& ctx, std::string event_name, Value data) override;
62 
63  void Track(Context const& ctx,
64  std::string event_name,
65  Value data,
66  hooks::HookContext const& hook_context) override;
67 
68  void Track(Context const& ctx, std::string event_name) override;
69 
70  void Track(Context const& ctx,
71  std::string event_name,
72  hooks::HookContext const& hook_context) override;
73 
74  void FlushAsync() override;
75 
76  void Identify(Context context) override;
77 
78  bool BoolVariation(Context const& ctx,
79  FlagKey const& key,
80  bool default_value) override;
81 
82  bool BoolVariation(Context const& ctx,
83  FlagKey const& key,
84  bool default_value,
85  hooks::HookContext const& hook_context) override;
86 
88  FlagKey const& key,
89  bool default_value) override;
90 
92  Context const& ctx,
93  FlagKey const& key,
94  bool default_value,
95  hooks::HookContext const& hook_context) override;
96 
97  std::string StringVariation(Context const& ctx,
98  FlagKey const& key,
99  std::string default_value) override;
100 
101  std::string StringVariation(Context const& ctx,
102  FlagKey const& key,
103  std::string default_value,
104  hooks::HookContext const& hook_context) override;
105 
107  Context const& ctx,
108  FlagKey const& key,
109  std::string default_value) override;
110 
112  Context const& ctx,
113  FlagKey const& key,
114  std::string default_value,
115  hooks::HookContext const& hook_context) override;
116 
117  double DoubleVariation(Context const& ctx,
118  FlagKey const& key,
119  double default_value) override;
120 
121  double DoubleVariation(Context const& ctx,
122  FlagKey const& key,
123  double default_value,
124  hooks::HookContext const& hook_context) override;
125 
127  Context const& ctx,
128  FlagKey const& key,
129  double default_value) override;
130 
132  Context const& ctx,
133  FlagKey const& key,
134  double default_value,
135  hooks::HookContext const& hook_context) override;
136 
137  int IntVariation(Context const& ctx,
138  FlagKey const& key,
139  int default_value) override;
140 
141  int IntVariation(Context const& ctx,
142  FlagKey const& key,
143  int default_value,
144  hooks::HookContext const& hook_context) override;
145 
147  FlagKey const& key,
148  int default_value) override;
149 
151  Context const& ctx,
152  FlagKey const& key,
153  int default_value,
154  hooks::HookContext const& hook_context) override;
155 
156  Value JsonVariation(Context const& ctx,
157  FlagKey const& key,
158  Value default_value) override;
159 
160  Value JsonVariation(Context const& ctx,
161  FlagKey const& key,
162  Value default_value,
163  hooks::HookContext const& hook_context) override;
164 
166  FlagKey const& key,
167  Value default_value) override;
168 
170  Context const& ctx,
171  FlagKey const& key,
172  Value default_value,
173  hooks::HookContext const& hook_context) override;
174 
176 
177  ~ClientImpl();
178 
179  std::future<bool> StartAsync() override;
180 
181  private:
182  [[nodiscard]] EvaluationDetail<Value> VariationInternal(
183  Context const& ctx,
184  FlagKey const& key,
185  Value const& default_value,
186  EventScope const& scope,
187  hooks::HookContext const& hook_context,
188  std::string const& method_name);
189 
190  template <typename T>
191  [[nodiscard]] EvaluationDetail<T> VariationDetail(
192  Context const& ctx,
193  enum Value::Type value_type,
194  IClient::FlagKey const& key,
195  Value const& default_value,
196  hooks::HookContext const& hook_context,
197  std::string const& method_name) {
198  auto result =
199  VariationInternal(ctx, key, default_value, events_with_reasons_,
200  hook_context, method_name);
201  if (result.Value().Type() == value_type) {
202  return EvaluationDetail<T>{result.Value(), result.VariationIndex(),
203  result.Reason()};
204  }
205  return EvaluationDetail<T>{EvaluationReason::ErrorKind::kWrongType,
206  default_value};
207  }
208 
209  [[nodiscard]] Value Variation(Context const& ctx,
210  enum Value::Type value_type,
211  std::string const& key,
212  Value const& default_value,
213  hooks::HookContext const& hook_context,
214  std::string const& method_name);
215 
216  [[nodiscard]] EvaluationDetail<Value> PostEvaluation(
217  std::string const& key,
218  Context const& context,
219  Value const& default_value,
221  result,
222  EventScope const& event_scope,
223  std::optional<data_model::Flag> const& flag);
224 
225  [[nodiscard]] std::optional<enum EvaluationReason::ErrorKind>
226  PreEvaluationChecks(Context const& context) const;
227 
228  void TrackInternal(Context const& ctx,
229  std::string event_name,
230  std::optional<Value> data,
231  std::optional<double> metric_value,
232  hooks::HookContext const& hook_context);
233 
234  std::future<bool> StartAsyncInternal(
235  std::function<bool(DataSourceStatus::DataSourceState)> predicate);
236 
237  void LogVariationCall(std::string const& key, bool flag_present) const;
238 
239  Config config_;
240  Logger logger_;
241 
243 
244  boost::asio::io_context ioc_;
245  boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
246  work_;
247 
249 
250  // This is the main polymorphic component that constitutes the
251  // guts of how data is retrieved (polling, streaming, persistent stores,
252  // etc.)
253  std::unique_ptr<data_interfaces::IDataSystem> data_system_;
254 
255  std::unique_ptr<events::IEventProcessor> event_processor_;
256 
257  mutable std::mutex init_mutex_;
258  std::condition_variable init_waiter_;
259 
260  evaluation::Evaluator evaluator_;
261 
262  EventScope const events_default_;
263  EventScope const events_with_reasons_;
264 
265  std::thread run_thread_;
266 };
267 } // namespace launchdarkly::server_side
Definition: context.hpp:29
Definition: evaluation_detail.hpp:18
T const & Value() const
Definition: evaluation_detail.cpp:29
ErrorKind
Definition: evaluation_reason.hpp:39
Definition: value.hpp:42
Definition: http_properties.hpp:70
Definition: all_flags_state.hpp:27
Options
Definition: all_flags_state.hpp:29
Definition: client_impl.hpp:33
EvaluationDetail< std::string > StringVariationDetail(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:507
EvaluationDetail< int > IntVariationDetail(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:579
void Track(Context const &ctx, std::string event_name, Value data, double metric_value) override
Definition: client_impl.cpp:265
Value JsonVariation(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:631
double DoubleVariation(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:563
EvaluationDetail< bool > BoolVariationDetail(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:473
void Identify(Context context) override
Definition: client_impl.cpp:156
int IntVariation(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:597
EvaluationDetail< double > DoubleVariationDetail(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:543
void FlushAsync() override
Definition: client_impl.cpp:310
EvaluationDetail< Value > JsonVariationDetail(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:613
std::future< bool > StartAsync() override
Definition: client_impl.cpp:162
std::string StringVariation(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:527
IDataSourceStatusProvider & DataSourceStatus() override
Definition: client_impl.cpp:647
bool BoolVariation(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:491
bool Initialized() const override
Definition: client_impl.cpp:180
Definition: event_scope.hpp:14
Definition: client.hpp:22
std::string FlagKey
Definition: client.hpp:27
Definition: data_source_status.hpp:69
Definition: data_source_status_manager.hpp:16
Definition: config.hpp:12