C++ Server-Side SDK
LaunchDarkly SDK
client_impl.hpp
1 #pragma once
2 
3 #include "data_components/big_segments/big_segment_store_status_provider.hpp"
4 #include "data_components/big_segments/big_segment_store_wrapper.hpp"
5 #include "data_components/status_notifications/data_source_status_manager.hpp"
6 #include "data_interfaces/system/idata_system.hpp"
7 #include "evaluation/evaluator.hpp"
8 #include "events/event_scope.hpp"
9 #include "hooks/hook_executor.hpp"
10 
11 #include <launchdarkly/config/client.hpp>
12 #include <launchdarkly/context.hpp>
13 #include <launchdarkly/data/evaluation_detail.hpp>
14 #include <launchdarkly/error.hpp>
15 #include <launchdarkly/events/event_processor_interface.hpp>
16 #include <launchdarkly/logging/logger.hpp>
17 #include <launchdarkly/server_side/client.hpp>
18 #include <launchdarkly/value.hpp>
19 
20 #include <boost/asio/executor_work_guard.hpp>
21 #include <boost/asio/io_context.hpp>
22 
23 #include <tl/expected.hpp>
24 
25 #include <condition_variable>
26 #include <cstdint>
27 #include <memory>
28 #include <optional>
29 #include <shared_mutex>
30 #include <thread>
31 #include <tuple>
32 
33 namespace launchdarkly::server_side {
34 
35 class ClientImpl : public IClient {
36  public:
37  ClientImpl(Config config, std::string const& version);
38 
39  ClientImpl(ClientImpl&&) = delete;
40  ClientImpl(ClientImpl const&) = delete;
41  ClientImpl& operator=(ClientImpl) = delete;
42  ClientImpl& operator=(ClientImpl&& other) = delete;
43 
44  bool Initialized() const override;
45 
46  using FlagKey = std::string;
47  [[nodiscard]] class AllFlagsState AllFlagsState(
48  Context const& context,
49  AllFlagsState::Options options =
51 
52  void Track(Context const& ctx,
53  std::string event_name,
54  Value data,
55  double metric_value) override;
56 
57  void Track(Context const& ctx,
58  std::string event_name,
59  Value data,
60  double metric_value,
61  hooks::HookContext const& hook_context) override;
62 
63  void Track(Context const& ctx, std::string event_name, Value data) override;
64 
65  void Track(Context const& ctx,
66  std::string event_name,
67  Value data,
68  hooks::HookContext const& hook_context) override;
69 
70  void Track(Context const& ctx, std::string event_name) override;
71 
72  void Track(Context const& ctx,
73  std::string event_name,
74  hooks::HookContext const& hook_context) override;
75 
76  void FlushAsync() override;
77 
78  void Identify(Context context) override;
79 
80  bool BoolVariation(Context const& ctx,
81  FlagKey const& key,
82  bool default_value) override;
83 
84  bool BoolVariation(Context const& ctx,
85  FlagKey const& key,
86  bool default_value,
87  hooks::HookContext const& hook_context) override;
88 
90  FlagKey const& key,
91  bool default_value) override;
92 
94  Context const& ctx,
95  FlagKey const& key,
96  bool default_value,
97  hooks::HookContext const& hook_context) override;
98 
99  std::string StringVariation(Context const& ctx,
100  FlagKey const& key,
101  std::string default_value) override;
102 
103  std::string StringVariation(
104  Context const& ctx,
105  FlagKey const& key,
106  std::string default_value,
107  hooks::HookContext const& hook_context) override;
108 
110  Context const& ctx,
111  FlagKey const& key,
112  std::string default_value) override;
113 
115  Context const& ctx,
116  FlagKey const& key,
117  std::string default_value,
118  hooks::HookContext const& hook_context) override;
119 
120  double DoubleVariation(Context const& ctx,
121  FlagKey const& key,
122  double default_value) override;
123 
124  double DoubleVariation(Context const& ctx,
125  FlagKey const& key,
126  double default_value,
127  hooks::HookContext const& hook_context) override;
128 
130  Context const& ctx,
131  FlagKey const& key,
132  double default_value) override;
133 
135  Context const& ctx,
136  FlagKey const& key,
137  double default_value,
138  hooks::HookContext const& hook_context) override;
139 
140  int IntVariation(Context const& ctx,
141  FlagKey const& key,
142  int default_value) override;
143 
144  int IntVariation(Context const& ctx,
145  FlagKey const& key,
146  int default_value,
147  hooks::HookContext const& hook_context) override;
148 
150  FlagKey const& key,
151  int default_value) override;
152 
154  Context const& ctx,
155  FlagKey const& key,
156  int default_value,
157  hooks::HookContext const& hook_context) override;
158 
159  Value JsonVariation(Context const& ctx,
160  FlagKey const& key,
161  Value default_value) override;
162 
163  Value JsonVariation(Context const& ctx,
164  FlagKey const& key,
165  Value default_value,
166  hooks::HookContext const& hook_context) override;
167 
169  FlagKey const& key,
170  Value default_value) override;
171 
173  Context const& ctx,
174  FlagKey const& key,
175  Value default_value,
176  hooks::HookContext const& hook_context) override;
177 
179 
181 
182  ~ClientImpl();
183 
184  std::future<bool> StartAsync() override;
185 
186  private:
187  [[nodiscard]] EvaluationDetail<Value> VariationInternal(
188  Context const& ctx,
189  FlagKey const& key,
190  Value const& default_value,
191  EventScope const& scope,
192  hooks::HookContext const& hook_context,
193  std::string const& method_name);
194 
195  template <typename T>
196  [[nodiscard]] EvaluationDetail<T> VariationDetail(
197  Context const& ctx,
198  enum Value::Type value_type,
199  IClient::FlagKey const& key,
200  Value const& default_value,
201  hooks::HookContext const& hook_context,
202  std::string const& method_name) {
203  auto result =
204  VariationInternal(ctx, key, default_value, events_with_reasons_,
205  hook_context, method_name);
206  if (result.Value().Type() == value_type) {
207  return EvaluationDetail<T>{result.Value(), result.VariationIndex(),
208  result.Reason()};
209  }
210  return EvaluationDetail<T>{EvaluationReason::ErrorKind::kWrongType,
211  default_value};
212  }
213 
214  [[nodiscard]] Value Variation(Context const& ctx,
215  enum Value::Type value_type,
216  std::string const& key,
217  Value const& default_value,
218  hooks::HookContext const& hook_context,
219  std::string const& method_name);
220 
221  [[nodiscard]] EvaluationDetail<Value> PostEvaluation(
222  std::string const& key,
223  Context const& context,
224  Value const& default_value,
226  result,
227  EventScope const& event_scope,
228  std::optional<data_model::Flag> const& flag);
229 
230  [[nodiscard]] std::optional<enum EvaluationReason::ErrorKind>
231  PreEvaluationChecks(Context const& context) const;
232 
233  void TrackInternal(Context const& ctx,
234  std::string event_name,
235  std::optional<Value> data,
236  std::optional<double> metric_value,
237  hooks::HookContext const& hook_context);
238 
239  std::future<bool> StartAsyncInternal(
240  std::function<bool(DataSourceStatus::DataSourceState)> predicate);
241 
242  void LogVariationCall(std::string const& key, bool flag_present) const;
243 
244  Config config_;
245  Logger logger_;
246 
248 
249  boost::asio::io_context ioc_;
250  boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
251  work_;
252 
254 
255  // This is the main polymorphic component that constitutes the
256  // guts of how data is retrieved (polling, streaming, persistent stores,
257  // etc.)
258  std::unique_ptr<data_interfaces::IDataSystem> data_system_;
259 
260  std::unique_ptr<events::IEventProcessor> event_processor_;
261 
262  // Null when Big Segments are not configured. Declared before evaluator_ so
263  // its pointer can be handed to the evaluator, and before
264  // big_segment_status_provider_ which shares ownership.
265  std::shared_ptr<data_components::BigSegmentStoreWrapper> big_segment_store_;
266  data_components::BigSegmentStoreStatusProvider big_segment_status_provider_;
267 
268  mutable std::mutex init_mutex_;
269  std::condition_variable init_waiter_;
270 
271  evaluation::Evaluator evaluator_;
272 
273  EventScope const events_default_;
274  EventScope const events_with_reasons_;
275 
276  std::thread run_thread_;
277 };
278 } // 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:35
EvaluationDetail< std::string > StringVariationDetail(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:639
EvaluationDetail< int > IntVariationDetail(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:712
void Track(Context const &ctx, std::string event_name, Value data, double metric_value) override
Definition: client_impl.cpp:392
Value JsonVariation(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:764
double DoubleVariation(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:696
EvaluationDetail< bool > BoolVariationDetail(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:604
void Identify(Context context) override
Definition: client_impl.cpp:283
int IntVariation(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:730
EvaluationDetail< double > DoubleVariationDetail(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:676
void FlushAsync() override
Definition: client_impl.cpp:437
IBigSegmentStoreStatusProvider & BigSegmentStoreStatus() override
Definition: client_impl.cpp:784
EvaluationDetail< Value > JsonVariationDetail(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:746
std::future< bool > StartAsync() override
Definition: client_impl.cpp:289
std::string StringVariation(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:659
IDataSourceStatusProvider & DataSourceStatus() override
Definition: client_impl.cpp:780
bool BoolVariation(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:623
bool Initialized() const override
Definition: client_impl.cpp:307
Definition: event_scope.hpp:14
Definition: big_segment_store_status.hpp:43
Definition: client.hpp:23
std::string FlagKey
Definition: client.hpp:28
Definition: data_source_status.hpp:69
Adapts a BigSegmentStoreWrapper to the public IBigSegmentStoreStatusProvider, converting the internal...
Definition: big_segment_store_status_provider.hpp:27
Definition: data_source_status_manager.hpp:16
Definition: config.hpp:14