C++ Server-Side SDK
LaunchDarkly SDK
streaming_synchronizer.hpp
1 #pragma once
2 
3 #include "../../data_interfaces/source/ifdv2_synchronizer.hpp"
4 
5 #include <launchdarkly/async/cancellation.hpp>
6 #include <launchdarkly/async/promise.hpp>
7 #include <launchdarkly/fdv2_protocol_handler.hpp>
8 #include <launchdarkly/logging/logger.hpp>
9 #include <launchdarkly/server_side/config/built/all_built.hpp>
10 #include <launchdarkly/sse/client.hpp>
11 
12 #include <boost/asio/any_io_executor.hpp>
13 #include <boost/url/url.hpp>
14 
15 #include <chrono>
16 #include <deque>
17 #include <memory>
18 #include <mutex>
19 #include <optional>
20 #include <string>
21 
22 namespace launchdarkly::server_side::data_systems {
23 
24 class FDv2StreamingSynchronizerTestPeer;
25 
39  friend class FDv2StreamingSynchronizerTestPeer;
40 
41  public:
47  boost::asio::any_io_executor const& executor,
48  Logger const& logger,
49  std::string streaming_base_url,
50  config::built::HttpProperties const& http_properties,
51  std::optional<std::string> filter_key,
52  std::chrono::milliseconds initial_reconnect_delay);
53 
54  ~FDv2StreamingSynchronizer() override;
55 
56  async::Future<data_interfaces::FDv2SourceResult> Next(
57  data_model::Selector selector) override;
58 
59  void Close() override;
60 
61  [[nodiscard]] std::string const& Identity() const override;
62 
63  private:
64  // Any state that may be accessed by async SSE callbacks needs to be inside
65  // this class, managed by a shared_ptr. All mutable members are guarded by
66  // the mutex.
67  class State {
68  friend class FDv2StreamingSynchronizerTestPeer;
69 
70  public:
71  State(Logger logger,
72  boost::asio::any_io_executor const& executor,
73  std::string streaming_base_url,
74  config::built::HttpProperties const& http_properties,
75  std::optional<std::string> filter_key,
76  std::chrono::milliseconds initial_reconnect_delay);
77 
88  async::Future<data_interfaces::FDv2SourceResult> Next(
89  data_model::Selector const& selector,
90  std::shared_ptr<State> self);
91 
97  void ClearPendingPromise();
98 
104  void Shutdown();
105 
106  private:
107  using HttpRequest =
108  boost::beast::http::request<boost::beast::http::string_body>;
109  using HttpResponseHeader = boost::beast::http::response_header<>;
110 
116  void EnsureStarted(data_model::Selector const& selector,
117  std::shared_ptr<State> self);
118 
123  void Notify(data_interfaces::FDv2SourceResult result);
124 
125  // SSE client callbacks.
126  void OnConnect(HttpRequest* req);
127  void OnResponse(HttpResponseHeader const& headers);
128  void OnEvent(sse::Event const& event);
129  void OnError(sse::Error const& error);
130 
131  // Logger is itself thread-safe.
132  Logger logger_;
133 
134  // Immutable state
135  std::string const streaming_base_url_;
136  config::built::HttpProperties const http_properties_;
137  std::optional<std::string> const filter_key_;
138  std::chrono::milliseconds const initial_reconnect_delay_;
139  boost::asio::any_io_executor const executor_;
140 
141  // Touched only from SSE callbacks, which all run on the same strand.
142  // No lock required.
143  FDv2ProtocolHandler protocol_handler_;
144 
145  // Mutable state, all guarded by mutex_.
146  std::mutex mutex_;
147  bool started_ = false;
148  bool closed_ = false;
149  // FDv1 fallback directive from the most recent SSE response.
150  std::optional<data_interfaces::FDv1FallbackDirective>
151  latest_fdv1_fallback_;
152  data_model::Selector latest_selector_;
153  std::optional<boost::urls::url> base_url_;
154  std::shared_ptr<sse::Client> sse_client_;
155  std::optional<async::Promise<data_interfaces::FDv2SourceResult>>
156  pending_promise_;
157  std::deque<data_interfaces::FDv2SourceResult> result_queue_;
158  };
159 
160  // Resolved by Close() or on destruction, cancelling any outstanding Next().
161  async::Promise<std::monostate> close_promise_;
162 
163  // Shared with async SSE callbacks.
164  std::shared_ptr<State> state_;
165 };
166 
167 } // namespace launchdarkly::server_side::data_systems
Definition: http_properties.hpp:70
std::string const & Identity() const override
Definition: streaming_synchronizer.cpp:435
void Close() override
Definition: streaming_synchronizer.cpp:428
async::Future< data_interfaces::FDv2SourceResult > Next(data_model::Selector selector) override
Definition: streaming_synchronizer.cpp:402
FDv2StreamingSynchronizer(boost::asio::any_io_executor const &executor, Logger const &logger, std::string streaming_base_url, config::built::HttpProperties const &http_properties, std::optional< std::string > filter_key, std::chrono::milliseconds initial_reconnect_delay)
Definition: streaming_synchronizer.cpp:384