Skip to content
3 changes: 2 additions & 1 deletion contract-tests/client-contract-tests/src/entity_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "entity_manager.hpp"
#include <boost/json/parse.hpp>

#include <launchdarkly/config/client.hpp>
#include <launchdarkly/context_builder.hpp>
#include <launchdarkly/serialization/json_context.hpp>

#include <boost/json.hpp>

using launchdarkly::LogLevel;
using namespace launchdarkly::client_side;

Expand Down
28 changes: 19 additions & 9 deletions contract-tests/server-contract-tests/src/entity_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "entity_manager.hpp"
#include <boost/json/parse.hpp>

#include <launchdarkly/context_builder.hpp>
#include <launchdarkly/serialization/json_context.hpp>
#include <launchdarkly/server_side/config/config_builder.hpp>

#include <boost/json.hpp>

using launchdarkly::LogLevel;
using namespace launchdarkly::server_side;

Expand All @@ -17,8 +18,16 @@ std::optional<std::string> EntityManager::create(ConfigParams const& in) {

auto config_builder = ConfigBuilder(in.credential);

auto default_endpoints =
launchdarkly::server_side::Defaults::ServiceEndpoints();
// The contract test service sets endpoints in a way that is disallowed
// for users. Specifically, it may set just 1 of the 3 endpoints, whereas
// we require all 3 to be set.
//
// To avoid that error being detected, we must configure the Endpoints
// builder with the 3 default URLs, which we can fetch by just calling Build
// on a new builder. That way when the contract tests set just 1 URL,
// the others have already been "set" so no error occurs.
auto const default_endpoints =
*config::builders::EndpointsBuilder().Build();

auto& endpoints =
config_builder.ServiceEndpoints()
Expand All @@ -37,18 +46,17 @@ std::optional<std::string> EntityManager::create(ConfigParams const& in) {
endpoints.EventsBaseUrl(*in.serviceEndpoints->events);
}
}

auto& datasource = config_builder.DataSource();
auto datasystem = config::builders::DataSystemBuilder::BackgroundSync();

if (in.streaming) {
if (in.streaming->baseUri) {
endpoints.StreamingBaseUrl(*in.streaming->baseUri);
}
if (in.streaming->initialRetryDelayMs) {
auto streaming = DataSourceBuilder::Streaming();
auto streaming = decltype(datasystem)::Streaming();
streaming.InitialReconnectDelay(
std::chrono::milliseconds(*in.streaming->initialRetryDelayMs));
datasource.Method(std::move(streaming));
datasystem.Synchronizer(std::move(streaming));
}
}

Expand All @@ -57,17 +65,19 @@ std::optional<std::string> EntityManager::create(ConfigParams const& in) {
endpoints.PollingBaseUrl(*in.polling->baseUri);
}
if (!in.streaming) {
auto method = DataSourceBuilder::Polling();
auto method = decltype(datasystem)::Polling();
if (in.polling->pollIntervalMs) {
method.PollInterval(
std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::milliseconds(
*in.polling->pollIntervalMs)));
}
datasource.Method(std::move(method));
datasystem.Synchronizer(std::move(method));
}
}

config_builder.DataSystem().Method(std::move(datasystem));

auto& event_config = config_builder.Events();

if (in.events) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ struct StreamingConfig<ServerSDK> {
std::string streaming_path;
};

inline bool operator==(StreamingConfig<ServerSDK> const& lhs,
StreamingConfig<ServerSDK> const& rhs) {
return lhs.initial_reconnect_delay == rhs.initial_reconnect_delay &&
lhs.streaming_path == rhs.streaming_path;
}

template <typename SDK>
struct PollingConfig;

Expand Down
2 changes: 1 addition & 1 deletion libs/common/include/launchdarkly/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum class Error : std::uint32_t {
kConfig_SDKKey_Empty = 400,
/* Client-side errors: 10000-19999 */
/* Server-side errors: 20000-29999 */

kConfig_DataSystem_LazyLoad_MissingSource = 20000,
kMax = std::numeric_limits<std::uint32_t>::max()
};

Expand Down
2 changes: 2 additions & 0 deletions libs/common/src/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ char const* ErrorToString(Error err) {
return "events: capacity must be non-zero";
case Error::kConfig_SDKKey_Empty:
return "sdk key: cannot be empty";
case Error::kConfig_DataSystem_LazyLoad_MissingSource:
return "data system: lazy load config requires a source";
case Error::kMax:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct LazyLoadBuilder {

/**
* \brief Specify the source of the data.
* \param source Component implementing ISerializedDataReader.
* \param source Component implementing ISerializedDataPullSource.
* \return Reference to this.
*/
LazyLoadBuilder& Source(SourcePtr source);
Expand All @@ -45,7 +45,7 @@ struct LazyLoadBuilder {
* before being refreshed from the database. The chosen \ref EvictionPolicy
* affects usage of this TTL. \return Reference to this.
*/
LazyLoadBuilder& CacheTTL(std::chrono::milliseconds ttl);
LazyLoadBuilder& CacheRefresh(std::chrono::milliseconds ttl);

/**
* \brief Specify the eviction policy when a data item's TTL expires.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <launchdarkly/server_side/integrations/serialized_descriptors.hpp>
#include <launchdarkly/server_side/integrations/iserialized_item_kind.hpp>
#include <launchdarkly/server_side/integrations/serialized_item_descriptor.hpp>

#include <tl/expected.hpp>

Expand Down Expand Up @@ -31,8 +32,7 @@ class ISerializedDataReader {
virtual ~ISerializedDataReader() = default;
ISerializedDataReader(ISerializedDataReader const& item) = delete;
ISerializedDataReader(ISerializedDataReader&& item) = delete;
ISerializedDataReader& operator=(ISerializedDataReader const&) =
delete;
ISerializedDataReader& operator=(ISerializedDataReader const&) = delete;
ISerializedDataReader& operator=(ISerializedDataReader&&) = delete;

struct Error {
Expand All @@ -55,7 +55,7 @@ class ISerializedDataReader {
* if the item did not exist, or an error. For a deleted item the serialized
* item descriptor may contain a std::nullopt for the serializedItem.
*/
virtual GetResult Get(integrations::IPersistentKind const& kind,
virtual GetResult Get(integrations::ISerializedItemKind const& kind,
std::string const& itemKey) const = 0;

/**
Expand All @@ -67,7 +67,8 @@ class ISerializedDataReader {
* @return Either all of the items of the type, or an error. If there are
* no items of the specified type, then return an empty collection.
*/
virtual AllResult All(integrations::IPersistentKind const& kind) const = 0;
virtual AllResult All(
integrations::ISerializedItemKind const& kind) const = 0;

virtual std::string const& Identity() const = 0;

Expand Down
6 changes: 6 additions & 0 deletions libs/server-sdk/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ target_sources(${LIBNAME}
boost.cpp
client.cpp
client_impl.cpp
data_source_status.cpp
config/config.cpp
config/config_builder.cpp
config/builders/data_system/background_sync_builder.cpp
config/builders/data_system/bootstrap_builder.cpp
config/builders/data_system/data_system_builder.cpp
config/builders/data_system/lazy_load_builder.cpp
config/builders/data_system/data_destination_builder.cpp
all_flags_state/all_flags_state.cpp
all_flags_state/json_all_flags_state.cpp
all_flags_state/all_flags_state_builder.cpp
Expand Down
21 changes: 12 additions & 9 deletions libs/server-sdk/src/bindings/c/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
#include <launchdarkly/server_side/config/config_builder.hpp>

using namespace launchdarkly::server_side;
using namespace launchdarkly::server_side::config::builders;

#define TO_BUILDER(ptr) (reinterpret_cast<ConfigBuilder*>(ptr))
#define FROM_BUILDER(ptr) (reinterpret_cast<LDServerConfigBuilder>(ptr))

#define TO_STREAM_BUILDER(ptr) \
(reinterpret_cast<DataSourceBuilder::Streaming*>(ptr))
(reinterpret_cast<DataSystemBuilder::BackgroundSync::Streaming*>(ptr))

#define FROM_STREAM_BUILDER(ptr) \
(reinterpret_cast<LDServerDataSourceStreamBuilder>(ptr))

#define TO_POLL_BUILDER(ptr) \
(reinterpret_cast<DataSourceBuilder::Polling*>(ptr))
(reinterpret_cast<DataSystemBuilder::BackgroundSync::Polling*>(ptr))

#define FROM_POLL_BUILDER(ptr) \
(reinterpret_cast<LDServerDataSourcePollBuilder>(ptr))
Expand Down Expand Up @@ -121,7 +122,7 @@ LD_EXPORT(void)
LDServerConfigBuilder_Offline(LDServerConfigBuilder b, bool offline) {
LD_ASSERT_NOT_NULL(b);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be fixed in subsequent PRs.

TO_BUILDER(b)->Offline(offline);
// TO_BUILDER(b)->Offline(offline);
}

LD_EXPORT(void)
Expand Down Expand Up @@ -171,8 +172,9 @@ LDServerConfigBuilder_DataSource_MethodStream(
LD_ASSERT_NOT_NULL(b);
LD_ASSERT_NOT_NULL(stream_builder);

DataSourceBuilder::Streaming* sb = TO_STREAM_BUILDER(stream_builder);
TO_BUILDER(b)->DataSource().Method(*sb);
BackgroundSyncBuilder::Streaming* sb = TO_STREAM_BUILDER(stream_builder);
TO_BUILDER(b)->DataSystem().Method(
BackgroundSyncBuilder().Synchronizer(*sb));
LDServerDataSourceStreamBuilder_Free(stream_builder);
}

Expand All @@ -183,14 +185,15 @@ LDServerConfigBuilder_DataSource_MethodPoll(
LD_ASSERT_NOT_NULL(b);
LD_ASSERT_NOT_NULL(poll_builder);

DataSourceBuilder::Polling* pb = TO_POLL_BUILDER(poll_builder);
TO_BUILDER(b)->DataSource().Method(*pb);
BackgroundSyncBuilder::Polling* pb = TO_POLL_BUILDER(poll_builder);
TO_BUILDER(b)->DataSystem().Method(
BackgroundSyncBuilder().Synchronizer(*pb));
LDServerDataSourcePollBuilder_Free(poll_builder);
}

LD_EXPORT(LDServerDataSourceStreamBuilder)
LDServerDataSourceStreamBuilder_New() {
return FROM_STREAM_BUILDER(new DataSourceBuilder::Streaming());
return FROM_STREAM_BUILDER(new BackgroundSyncBuilder::Streaming());
}

LD_EXPORT(void)
Expand All @@ -209,7 +212,7 @@ LDServerDataSourceStreamBuilder_Free(LDServerDataSourceStreamBuilder b) {
}

LD_EXPORT(LDServerDataSourcePollBuilder) LDServerDataSourcePollBuilder_New() {
return FROM_POLL_BUILDER(new DataSourceBuilder::Polling());
return FROM_POLL_BUILDER(new BackgroundSyncBuilder::Polling());
}

LD_EXPORT(void)
Expand Down
16 changes: 7 additions & 9 deletions libs/server-sdk/src/bindings/c/sdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ struct Detail;
#define FROM_DETAIL(ptr) (reinterpret_cast<LDEvalDetail>(ptr))

#define TO_DATASOURCESTATUS(ptr) \
(reinterpret_cast< \
launchdarkly::server_side::data_sources::DataSourceStatus*>(ptr))
(reinterpret_cast<launchdarkly::server_side::DataSourceStatus*>(ptr))

#define FROM_DATASOURCESTATUS(ptr) \
(reinterpret_cast<LDServerDataSourceStatus>(ptr))

Expand Down Expand Up @@ -356,10 +356,8 @@ LDServerDataSourceStatus_GetLastError(LDServerDataSourceStatus status) {
if (!error) {
return nullptr;
}
return FROM_DATASOURCESTATUS_ERRORINFO(
new data_sources::DataSourceStatus::ErrorInfo(
error->Kind(), error->StatusCode(), error->Message(),
error->Time()));
return FROM_DATASOURCESTATUS_ERRORINFO(new DataSourceStatus::ErrorInfo(
error->Kind(), error->StatusCode(), error->Message(), error->Time()));
}

LD_EXPORT(time_t)
Expand Down Expand Up @@ -387,7 +385,7 @@ LDServerSDK_DataSourceStatus_OnStatusChange(
if (listener.StatusChanged) {
auto connection =
TO_SDK(sdk)->DataSourceStatus().OnDataSourceStatusChange(
[listener](data_sources::DataSourceStatus status) {
[listener](DataSourceStatus status) {
listener.StatusChanged(FROM_DATASOURCESTATUS(&status),
listener.UserData);
});
Expand All @@ -402,8 +400,8 @@ LD_EXPORT(LDServerDataSourceStatus)
LDServerSDK_DataSourceStatus_Status(LDServerSDK sdk) {
LD_ASSERT_NOT_NULL(sdk);

return FROM_DATASOURCESTATUS(new data_sources::DataSourceStatus(
TO_SDK(sdk)->DataSourceStatus().Status()));
return FROM_DATASOURCESTATUS(
new DataSourceStatus(TO_SDK(sdk)->DataSourceStatus().Status()));
}

LD_EXPORT(void) LDServerDataSourceStatus_Free(LDServerDataSourceStatus status) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
#include <launchdarkly/server_side/config/builders/data_system/background_sync_builder.hpp>

#include "defaults.hpp"

namespace launchdarkly::server_side::config::builders {

BackgroundSyncBuilder::BackgroundSyncBuilder()
: bootstrap_builder_(), config_() {}
: bootstrap_builder_(), config_(Defaults::BackgroundSyncConfig()) {}

BootstrapBuilder& BackgroundSyncBuilder::Bootstrapper() {
return bootstrap_builder_;
}

BackgroundSyncBuilder& BackgroundSyncBuilder::Synchronizer(Streaming source) {
config_.source_.method = source.Build();
config_.synchronizer_ = source.Build();
return *this;
}

BackgroundSyncBuilder& BackgroundSyncBuilder::Synchronizer(Polling source) {
config_.source_.method = source.Build();
config_.synchronizer_ = source.Build();
return *this;
}

Expand Down
7 changes: 6 additions & 1 deletion libs/server-sdk/src/config/builders/data_system/defaults.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ struct Defaults {
return std::nullopt;
}

static auto SynchronizerConfig()
-> built::BackgroundSyncConfig::StreamingConfig {
return {std::chrono::seconds(1), "/all"};
}

static auto BackgroundSyncConfig() -> built::BackgroundSyncConfig {
return {BootstrapConfig(), DataSourceConfig(), DataDestinationConfig()};
return {BootstrapConfig(), SynchronizerConfig(), DataDestinationConfig()};
}

static auto LazyLoadConfig() -> built::LazyLoadConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace launchdarkly::server_side::config::builders {

LazyLoadBuilder::LazyLoadBuilder() : config_(Defaults::LazyLoadConfig()) {}

LazyLoadBuilder& LazyLoadBuilder::CacheTTL(
LazyLoadBuilder& LazyLoadBuilder::CacheRefresh(
std::chrono::milliseconds const ttl) {
config_.eviction_ttl = ttl;
return *this;
Expand Down
6 changes: 3 additions & 3 deletions libs/server-sdk/src/data_components/kinds/kinds.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

#include <launchdarkly/server_side/integrations/serialized_descriptors.hpp>
#include <launchdarkly/server_side/integrations/iserialized_item_kind.hpp>

namespace launchdarkly::server_side::data_components {

class SegmentKind final : public integrations::IPersistentKind {
class SegmentKind final : public integrations::ISerializedItemKind {
public:
std::string const& Namespace() const override;
std::uint64_t Version(std::string const& data) const override;
Expand All @@ -15,7 +15,7 @@ class SegmentKind final : public integrations::IPersistentKind {
static inline std::string const namespace_ = "segments";
};

class FlagKind final : public integrations::IPersistentKind {
class FlagKind final : public integrations::ISerializedItemKind {
public:
std::string const& Namespace() const override;
std::uint64_t Version(std::string const& data) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ JsonDataReader::GetSegment(std::string const& key) const {
data_interfaces::IDataReader::Collection<data_model::FlagDescriptor>
JsonDataReader::AllFlags() const {
// TODO: deserialize then return
return tl::make_unexpected("Not implemented");
}

data_interfaces::IDataReader::Collection<data_model::SegmentDescriptor>
JsonDataReader::AllSegments() const {
// TODO: deserialize then return
return tl::make_unexpected("Not implemented");
}

std::string const& JsonDataReader::Identity() const {
Expand Down
Loading