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 
8 #include <launchdarkly/config/client.hpp>
9 #include <launchdarkly/context.hpp>
10 #include <launchdarkly/data/evaluation_detail.hpp>
11 #include <launchdarkly/error.hpp>
12 #include <launchdarkly/events/event_processor_interface.hpp>
13 #include <launchdarkly/logging/logger.hpp>
14 #include <launchdarkly/server_side/client.hpp>
15 #include <launchdarkly/value.hpp>
16 
17 #include <boost/asio/executor_work_guard.hpp>
18 #include <boost/asio/io_context.hpp>
19 
20 #include <tl/expected.hpp>
21 
22 #include <condition_variable>
23 #include <cstdint>
24 #include <memory>
25 #include <optional>
26 #include <shared_mutex>
27 #include <thread>
28 #include <tuple>
29 
30 namespace launchdarkly::server_side {
31 
32 class ClientImpl : public IClient {
33  public:
34  ClientImpl(Config config, std::string const& version);
35 
36  ClientImpl(ClientImpl&&) = delete;
37  ClientImpl(ClientImpl const&) = delete;
38  ClientImpl& operator=(ClientImpl) = delete;
39  ClientImpl& operator=(ClientImpl&& other) = delete;
40 
41  bool Initialized() const override;
42 
43  using FlagKey = std::string;
44  [[nodiscard]] class AllFlagsState AllFlagsState(
45  Context const& context,
46  AllFlagsState::Options options =
48 
49  void Track(Context const& ctx,
50  std::string event_name,
51  Value data,
52  double metric_value) override;
53 
54  void Track(Context const& ctx, std::string event_name, Value data) override;
55 
56  void Track(Context const& ctx, std::string event_name) override;
57 
58  void FlushAsync() override;
59 
60  void Identify(Context context) override;
61 
62  bool BoolVariation(Context const& ctx,
63  FlagKey const& key,
64  bool default_value) override;
65 
67  FlagKey const& key,
68  bool default_value) override;
69 
70  std::string StringVariation(Context const& ctx,
71  FlagKey const& key,
72  std::string default_value) override;
73 
75  Context const& ctx,
76  FlagKey const& key,
77  std::string default_value) override;
78 
79  double DoubleVariation(Context const& ctx,
80  FlagKey const& key,
81  double default_value) override;
82 
84  Context const& ctx,
85  FlagKey const& key,
86  double default_value) override;
87 
88  int IntVariation(Context const& ctx,
89  FlagKey const& key,
90  int default_value) override;
91 
93  FlagKey const& key,
94  int default_value) override;
95 
96  Value JsonVariation(Context const& ctx,
97  FlagKey const& key,
98  Value default_value) override;
99 
101  FlagKey const& key,
102  Value default_value) override;
103 
105 
106  ~ClientImpl();
107 
108  std::future<bool> StartAsync() override;
109 
110  private:
111  [[nodiscard]] EvaluationDetail<Value> VariationInternal(
112  Context const& ctx,
113  FlagKey const& key,
114  Value const& default_value,
115  EventScope const& scope);
116 
117  template <typename T>
118  [[nodiscard]] EvaluationDetail<T> VariationDetail(
119  Context const& ctx,
120  enum Value::Type value_type,
121  IClient::FlagKey const& key,
122  Value const& default_value) {
123  auto result =
124  VariationInternal(ctx, key, default_value, events_with_reasons_);
125  if (result.Value().Type() == value_type) {
126  return EvaluationDetail<T>{result.Value(), result.VariationIndex(),
127  result.Reason()};
128  }
129  return EvaluationDetail<T>{EvaluationReason::ErrorKind::kWrongType,
130  default_value};
131  }
132 
133  [[nodiscard]] Value Variation(Context const& ctx,
134  enum Value::Type value_type,
135  std::string const& key,
136  Value const& default_value);
137 
138  [[nodiscard]] EvaluationDetail<Value> PostEvaluation(
139  std::string const& key,
140  Context const& context,
141  Value const& default_value,
143  result,
144  EventScope const& event_scope,
145  std::optional<data_model::Flag> const& flag);
146 
147  [[nodiscard]] std::optional<enum EvaluationReason::ErrorKind>
148  PreEvaluationChecks(Context const& context) const;
149 
150  void TrackInternal(Context const& ctx,
151  std::string event_name,
152  std::optional<Value> data,
153  std::optional<double> metric_value);
154 
155  std::future<bool> StartAsyncInternal(
156  std::function<bool(DataSourceStatus::DataSourceState)> predicate);
157 
158  void LogVariationCall(std::string const& key, bool flag_present) const;
159 
160  Config config_;
161  Logger logger_;
162 
164 
165  boost::asio::io_context ioc_;
166  boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
167  work_;
168 
170 
171  // This is the main polymorphic component that constitutes the
172  // guts of how data is retrieved (polling, streaming, persistent stores,
173  // etc.)
174  std::unique_ptr<data_interfaces::IDataSystem> data_system_;
175 
176  std::unique_ptr<events::IEventProcessor> event_processor_;
177 
178  mutable std::mutex init_mutex_;
179  std::condition_variable init_waiter_;
180 
181  evaluation::Evaluator evaluator_;
182 
183  EventScope const events_default_;
184  EventScope const events_with_reasons_;
185 
186  std::thread run_thread_;
187 };
188 } // 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:26
Definition: all_flags_state.hpp:26
Options
Definition: all_flags_state.hpp:28
Definition: client_impl.hpp:32
EvaluationDetail< std::string > StringVariationDetail(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:381
EvaluationDetail< int > IntVariationDetail(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:409
void Track(Context const &ctx, std::string event_name, Value data, double metric_value) override
Definition: client_impl.cpp:230
Value JsonVariation(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:429
double DoubleVariation(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:403
EvaluationDetail< bool > BoolVariationDetail(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:368
void Identify(Context context) override
Definition: client_impl.cpp:142
int IntVariation(Context const &ctx, FlagKey const &key, int default_value) override
Definition: client_impl.cpp:416
EvaluationDetail< double > DoubleVariationDetail(Context const &ctx, FlagKey const &key, double default_value) override
Definition: client_impl.cpp:395
void FlushAsync() override
Definition: client_impl.cpp:247
EvaluationDetail< Value > JsonVariationDetail(Context const &ctx, FlagKey const &key, Value default_value) override
Definition: client_impl.cpp:422
std::future< bool > StartAsync() override
Definition: client_impl.cpp:148
std::string StringVariation(Context const &ctx, FlagKey const &key, std::string default_value) override
Definition: client_impl.cpp:389
IDataSourceStatusProvider & DataSourceStatus() override
Definition: client_impl.cpp:435
bool BoolVariation(Context const &ctx, FlagKey const &key, bool default_value) override
Definition: client_impl.cpp:375
bool Initialized() const override
Definition: client_impl.cpp:166
Definition: event_scope.hpp:14
Definition: client.hpp:21
std::string FlagKey
Definition: client.hpp:26
Definition: data_source_status.hpp:69
Definition: data_source_status_manager.hpp:16
Definition: config.hpp:8