Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
#pragma once

#pragma once

#include <chrono>
#include <cstddef>
#include <functional>
#include <memory>
#include <optional>
#include <ostream>
#include <utility>

#include <launchdarkly/connection.hpp>
#include <launchdarkly/data_sources/data_source_status_base.hpp>

namespace launchdarkly::server_side::data_sources {
namespace launchdarkly::server_side {

/**
* Enumeration of possible data source states.
Expand Down Expand Up @@ -85,7 +81,7 @@ class IDataSourceStatusProvider {
* @return A IConnection which can be used to stop listening to the status.
*/
virtual std::unique_ptr<IConnection> OnDataSourceStatusChange(
std::function<void(data_sources::DataSourceStatus status)> handler) = 0;
std::function<void(DataSourceStatus status)> handler) = 0;

/**
* Listen to changes to the data source status, with ability for listener
Expand All @@ -96,7 +92,7 @@ class IDataSourceStatusProvider {
* @return A IConnection which can be used to stop listening to the status.
*/
virtual std::unique_ptr<IConnection> OnDataSourceStatusChangeEx(
std::function<bool(data_sources::DataSourceStatus status)> handler) = 0;
std::function<bool(DataSourceStatus status)> handler) = 0;

virtual ~IDataSourceStatusProvider() = default;
IDataSourceStatusProvider(IDataSourceStatusProvider const& item) = delete;
Expand All @@ -114,4 +110,4 @@ std::ostream& operator<<(std::ostream& out,

std::ostream& operator<<(std::ostream& out, DataSourceStatus const& status);

} // namespace launchdarkly::server_side::data_sources
} // namespace launchdarkly::server_side
17 changes: 8 additions & 9 deletions libs/server-sdk/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ target_sources(${LIBNAME}
all_flags_state/json_all_flags_state.cpp
all_flags_state/all_flags_state_builder.cpp
data_sources/data_source_update_sink.hpp
data_store/data_store.hpp
data_store/data_store_updater.hpp
data_store/data_store_updater.cpp
data_store/memory_store.cpp
data_store/dependency_tracker.hpp
data_store/dependency_tracker.cpp
data_store/descriptors.hpp
data_sources/data_source_event_handler.cpp
data_sources/data_source_event_handler.hpp
data_sources/data_source_status.cpp
Expand All @@ -41,6 +34,14 @@ target_sources(${LIBNAME}
data_sources/streaming_data_source.hpp
data_sources/streaming_data_source.cpp
data_sources/null_data_source.cpp
data_components/change_notifier/change_notifier.hpp
data_components/change_notifier/change_notifier.cpp
data_components/dependency_tracker/dependency_tracker.hpp
data_components/dependency_tracker/dependency_tracker.cpp
data_components/expiration_tracker/expiration_tracker.hpp
data_components/expiration_tracker/expiration_tracker.cpp
data_components/memory_store/memory_store.hpp
data_components/memory_store/memory_store.cpp
data_interfaces.cpp
evaluation/evaluator.cpp
evaluation/rules.cpp
Expand All @@ -50,8 +51,6 @@ target_sources(${LIBNAME}
evaluation/detail/evaluation_stack.cpp
evaluation/detail/semver_operations.cpp
evaluation/detail/timestamp_operations.cpp
data_store/persistent/expiration_tracker.hpp
data_store/persistent/expiration_tracker.cpp
events/event_factory.cpp
bindings/c/sdk.cpp
bindings/c/builder.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "all_flags_state_builder.hpp"

#include <launchdarkly/data_model/flag.hpp>

namespace launchdarkly::server_side {

bool IsDebuggingEnabled(std::optional<std::uint64_t> debug_events_until);
Expand Down
10 changes: 6 additions & 4 deletions libs/server-sdk/src/all_flags_state/all_flags_state_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include <launchdarkly/server_side/client.hpp>

#include "../data_store/data_store.hpp"
#include "../evaluation/evaluator.hpp"
#include <launchdarkly/value.hpp>

#include <string>
#include <unordered_map>

namespace launchdarkly::server_side {

Expand All @@ -16,7 +18,7 @@ class AllFlagsStateBuilder {
* Constructs a builder capable of generating a AllFlagsState structure.
* @param options Options affecting the behavior of the builder.
*/
AllFlagsStateBuilder(AllFlagsState::Options options);
explicit AllFlagsStateBuilder(AllFlagsState::Options options);

/**
* Adds a flag, including its evaluation result and additional state.
Expand All @@ -36,7 +38,7 @@ class AllFlagsStateBuilder {
[[nodiscard]] AllFlagsState Build();

private:
enum AllFlagsState::Options options_;
AllFlagsState::Options options_;
std::unordered_map<std::string, AllFlagsState::State> flags_state_;
std::unordered_map<std::string, Value> evaluations_;
};
Expand Down
2 changes: 1 addition & 1 deletion libs/server-sdk/src/client_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

#include "all_flags_state/all_flags_state_builder.hpp"
#include "client_impl.hpp"
#include "data_components/memory_store/memory_store.hpp"
#include "data_sources/null_data_source.hpp"
#include "data_sources/polling_data_source.hpp"
#include "data_sources/streaming_data_source.hpp"
#include "data_store/memory_store.hpp"

#include <launchdarkly/encoding/sha_256.hpp>
#include <launchdarkly/events/asio_event_processor.hpp>
Expand Down
10 changes: 5 additions & 5 deletions libs/server-sdk/src/client_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
#include <launchdarkly/server_side/client.hpp>
#include <launchdarkly/value.hpp>

#include "data_sources/data_source_status_manager.hpp"
#include "data_sources/data_source_update_sink.hpp"

#include "data_store/data_store_updater.hpp"
#include "data_store/memory_store.hpp"
#include "data_components/change_notifier/change_notifier.hpp"
#include "data_components/memory_store/memory_store.hpp"
#include "data_components/status_notifications/data_source_status_manager.hpp"

#include "evaluation/evaluator.hpp"

Expand Down Expand Up @@ -173,10 +173,10 @@ class ClientImpl : public IClient {
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
work_;

data_store::MemoryStore memory_store_;
data_components::MemoryStore memory_store_;

data_sources::DataSourceStatusManager status_manager_;
data_store::DataStoreUpdater data_store_updater_;
data_components::ChangeNotifier data_store_updater_;

std::shared_ptr<::launchdarkly::data_sources::IDataSource> data_source_;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
#include "data_store_updater.hpp"
#include "change_notifier.hpp"

#include <launchdarkly/signals/boost_signal_connection.hpp>
#include <utility>

namespace launchdarkly::server_side::data_store {
namespace launchdarkly::server_side::data_components {

std::unique_ptr<IConnection> DataStoreUpdater::OnFlagChange(
std::unique_ptr<IConnection> ChangeNotifier::OnFlagChange(
launchdarkly::server_side::IChangeNotifier::ChangeHandler handler) {
std::lock_guard lock{signal_mutex_};

return std::make_unique<launchdarkly::internal::signals::SignalConnection>(
signals_.connect(handler));
}

void DataStoreUpdater::Init(launchdarkly::data_model::SDKDataSet data_set) {
void ChangeNotifier::Init(launchdarkly::data_model::SDKDataSet data_set) {
// Optional outside the HasListeners() scope, this allows for the changes
// to be calculated before the update and then the notification to be
// sent after the update completes.
std::optional<DependencySet> change_notifications;
if (HasListeners()) {
DependencySet updated_items;

CalculateChanges(DataKind::kFlag, store_.AllFlags(), data_set.flags,
CalculateChanges(DataKind::kFlag, source_.AllFlags(), data_set.flags,
updated_items);
CalculateChanges(DataKind::kSegment, store_.AllSegments(),
CalculateChanges(DataKind::kSegment, source_.AllSegments(),
data_set.segments, updated_items);
change_notifications = updated_items;
}
Expand All @@ -44,23 +44,23 @@ void DataStoreUpdater::Init(launchdarkly::data_model::SDKDataSet data_set) {
}
}

void DataStoreUpdater::Upsert(std::string const& key,
data_store::FlagDescriptor flag) {
UpsertCommon(DataKind::kFlag, key, store_.GetFlag(key), std::move(flag));
void ChangeNotifier::Upsert(std::string const& key,
data_model::FlagDescriptor flag) {
UpsertCommon(DataKind::kFlag, key, source_.GetFlag(key), std::move(flag));
}

void DataStoreUpdater::Upsert(std::string const& key,
data_store::SegmentDescriptor segment) {
UpsertCommon(DataKind::kSegment, key, store_.GetSegment(key),
void ChangeNotifier::Upsert(std::string const& key,
data_model::SegmentDescriptor segment) {
UpsertCommon(DataKind::kSegment, key, source_.GetSegment(key),
std::move(segment));
}

bool DataStoreUpdater::HasListeners() const {
bool ChangeNotifier::HasListeners() const {
std::lock_guard lock{signal_mutex_};
return !signals_.empty();
}

void DataStoreUpdater::NotifyChanges(DependencySet changes) {
void ChangeNotifier::NotifyChanges(DependencySet changes) {
std::lock_guard lock{signal_mutex_};
auto flag_changes = changes.SetForKind(DataKind::kFlag);
// Only emit an event if there are changes.
Expand All @@ -69,8 +69,14 @@ void DataStoreUpdater::NotifyChanges(DependencySet changes) {
}
}

DataStoreUpdater::DataStoreUpdater(IDataSourceUpdateSink& sink,
IDataStore const& store)
: sink_(sink), store_(store) {}
ChangeNotifier::ChangeNotifier(IDestination& sink,
data_interfaces::IStore const& source)
: sink_(sink), source_(source) {}

} // namespace launchdarkly::server_side::data_store
std::string const& ChangeNotifier::Identity() const {
static std::string const identity =
"change notifier for " + sink_.Identity();
return identity;
}

} // namespace launchdarkly::server_side::data_components
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#pragma once

#include "../data_sources/data_source_update_sink.hpp"
#include "data_store.hpp"
#include "dependency_tracker.hpp"
#include "../../data_interfaces/destination/idestination.hpp"
#include "../../data_interfaces/store/istore.hpp"
#include "../dependency_tracker/dependency_tracker.hpp"

#include <launchdarkly/data_model/descriptors.hpp>
#include <launchdarkly/server_side/change_notifier.hpp>

#include <boost/signals2/signal.hpp>

#include <memory>

namespace launchdarkly::server_side::data_store {
namespace launchdarkly::server_side::data_components {

class DataStoreUpdater
: public launchdarkly::server_side::data_sources::IDataSourceUpdateSink,
public launchdarkly::server_side::IChangeNotifier {
class ChangeNotifier final : public data_interfaces::IDestination,
public IChangeNotifier {
public:
template <typename Storage>
using Collection = data_model::SDKDataSet::Collection<std::string, Storage>;
Expand All @@ -26,29 +26,33 @@ class DataStoreUpdater
using SharedCollection =
std::unordered_map<std::string, SharedItem<Storage>>;

DataStoreUpdater(IDataSourceUpdateSink& sink, IDataStore const& store);
ChangeNotifier(IDestination& sink, data_interfaces::IStore const& source);

std::unique_ptr<IConnection> OnFlagChange(ChangeHandler handler) override;

void Init(launchdarkly::data_model::SDKDataSet data_set) override;
void Upsert(std::string const& key, FlagDescriptor flag) override;
void Upsert(std::string const& key, SegmentDescriptor segment) override;
~DataStoreUpdater() override = default;
void Init(data_model::SDKDataSet data_set) override;
void Upsert(std::string const& key,
data_model::FlagDescriptor flag) override;
void Upsert(std::string const& key,
data_model::SegmentDescriptor segment) override;

DataStoreUpdater(DataStoreUpdater const& item) = delete;
DataStoreUpdater(DataStoreUpdater&& item) = delete;
DataStoreUpdater& operator=(DataStoreUpdater const&) = delete;
DataStoreUpdater& operator=(DataStoreUpdater&&) = delete;
[[nodiscard]] std::string const& Identity() const override;

~ChangeNotifier() override = default;

ChangeNotifier(ChangeNotifier const& item) = delete;
ChangeNotifier(ChangeNotifier&& item) = delete;
ChangeNotifier& operator=(ChangeNotifier const&) = delete;
ChangeNotifier& operator=(ChangeNotifier&&) = delete;

private:
bool HasListeners() const;

template <typename FlagOrSegment>
void UpsertCommon(
DataKind kind,
std::string key,
SharedItem<FlagOrSegment> existing,
launchdarkly::data_model::ItemDescriptor<FlagOrSegment> updated) {
void UpsertCommon(DataKind kind,
std::string key,
SharedItem<FlagOrSegment> existing,
data_model::ItemDescriptor<FlagOrSegment> updated) {
if (existing && (updated.version <= existing->version)) {
// Out of order update, ignore it.
return;
Expand Down Expand Up @@ -101,8 +105,8 @@ class DataStoreUpdater

void NotifyChanges(DependencySet changes);

IDataSourceUpdateSink& sink_;
IDataStore const& store_;
IDestination& sink_;
data_interfaces::IStore const& source_;

boost::signals2::signal<void(std::shared_ptr<ChangeSet>)> signals_;

Expand All @@ -118,4 +122,4 @@ class DataStoreUpdater

DependencyTracker dependency_tracker_;
};
} // namespace launchdarkly::server_side::data_store
} // namespace launchdarkly::server_side::data_components
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <cstddef>

namespace launchdarkly::server_side::data_components {
enum class DataKind : std::size_t { kFlag = 0, kSegment = 1, kKindCount = 2 };
} // namespace launchdarkly::server_side::data_components
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@

#include <type_traits>

namespace launchdarkly::server_side::data_store {
namespace launchdarkly::server_side::data_components {

DependencySet::DependencySet()
: data_{
TaggedData<std::set<std::string>>(DataKind::kFlag),
TaggedData<std::set<std::string>>(DataKind::kSegment),
} {}

void DependencySet::Set(DataKind kind, std::string key) {
void DependencySet::Set(DataKind const kind, std::string key) {
Data(kind).emplace(std::move(key));
}

void DependencySet::Remove(DataKind kind, std::string const& key) {
void DependencySet::Remove(DataKind const kind, std::string const& key) {
Data(kind).erase(key);
}

bool DependencySet::Contains(DataKind kind, std::string const& key) const {
bool DependencySet::Contains(DataKind const kind,
std::string const& key) const {
return Data(kind).count(key) != 0;
}

Expand Down Expand Up @@ -194,4 +195,4 @@ void DependencyTracker::Clear() {
dependencies_from_.Clear();
}

} // namespace launchdarkly::server_side::data_store
} // namespace launchdarkly::server_side::data_components
Loading