Skip to content

Commit 10265fd

Browse files
authored
feat: implement Client type (#21)
* implemented launchdarkly::client_side::Client type * Add minimal client test * Update config_builder tests
1 parent 15199f1 commit 10265fd

File tree

17 files changed

+320
-104
lines changed

17 files changed

+320
-104
lines changed

apps/hello-cpp/main.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ using launchdarkly::LogLevel;
1818
int main() {
1919
Logger logger(std::make_unique<ConsoleBackend>("Hello"));
2020

21-
if (auto num = launchdarkly::foo()) {
22-
LD_LOG(logger, LogLevel::kInfo) << "Got: " << *num << '\n';
23-
} else {
24-
LD_LOG(logger, LogLevel::kInfo) << "Got nothing\n";
25-
}
26-
2721
net::io_context ioc;
2822

2923
char const* key = std::getenv("STG_SDK_KEY");

bindings/c/src/api.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
11
#include "launchdarkly/client_side/api.hpp"
22
#include <launchdarkly/api.h>
3-
4-
bool launchdarkly_foo(int32_t* out_result) {
5-
if (auto val = launchdarkly::foo()) {
6-
*out_result = *val;
7-
return true;
8-
}
9-
return false;
10-
}
Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,56 @@
11
#pragma once
22

3-
#include "cstdint"
4-
#include "optional"
3+
#include <boost/asio/io_context.hpp>
4+
#include <cstdint>
5+
#include <memory>
6+
#include <optional>
7+
#include <thread>
8+
#include <tl/expected.hpp>
9+
#include "config/client.hpp"
10+
#include "context.hpp"
11+
#include "error.hpp"
12+
#include "events/event_processor.hpp"
13+
#include "logger.hpp"
14+
#include "value.hpp"
515

6-
namespace launchdarkly {
7-
std::optional<std::int32_t> foo();
8-
} // namespace launchdarkly
16+
namespace launchdarkly::client_side {
17+
class Client {
18+
public:
19+
Client(client::Config config, Context context);
20+
21+
using FlagKey = std::string;
22+
[[nodiscard]] std::unordered_map<FlagKey, Value> AllFlags() const;
23+
24+
void Track(std::string event_name, Value data, double metric_value);
25+
26+
void Track(std::string event_name, Value data);
27+
28+
void Track(std::string event_name);
29+
30+
void AsyncFlush();
31+
32+
void AsyncIdentify(Context context);
33+
34+
bool BoolVariation(FlagKey const& key, bool default_value);
35+
36+
std::string StringVariation(FlagKey const& key, std::string default_value);
37+
38+
double DoubleVariation(FlagKey const& key, double default_value);
39+
40+
int IntVariation(FlagKey const& key, int default_value);
41+
42+
Value JsonVariation(FlagKey const& key, Value default_value);
43+
44+
private:
45+
void TrackInternal(std::string event_name,
46+
std::optional<Value> data,
47+
std::optional<double> metric_value);
48+
49+
Logger logger_;
50+
std::thread thread_;
51+
boost::asio::io_context ioc_;
52+
Context context_;
53+
std::unique_ptr<events::IEventProcessor> event_processor_;
54+
};
55+
56+
} // namespace launchdarkly::client_side

libs/client-sdk/src/api.cpp

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,78 @@
11
#include "launchdarkly/client_side/api.hpp"
2-
3-
#include <cstdint>
2+
#include <chrono>
43
#include <optional>
4+
#include <utility>
5+
6+
#include "console_backend.hpp"
7+
#include "events/client_events.hpp"
8+
#include "events/detail/asio_event_processor.hpp"
59

6-
namespace launchdarkly {
10+
namespace launchdarkly::client_side {
711

8-
auto const kAnswerToLifeTheUniverseAndEverything = 42;
12+
Client::Client(client::Config config, Context context)
13+
: logger_(config.take_logger()),
14+
context_(std::move(context)),
15+
event_processor_(
16+
std::make_unique<launchdarkly::events::detail::AsioEventProcessor>(
17+
ioc_.get_executor(),
18+
config.events_config(),
19+
config.service_endpoints(),
20+
config.sdk_key(),
21+
logger_)) {}
22+
23+
std::unordered_map<Client::FlagKey, Value> Client::AllFlags() const {
24+
return {};
25+
}
926

10-
std::optional<std::int32_t> foo() {
11-
return kAnswerToLifeTheUniverseAndEverything;
27+
void Client::TrackInternal(std::string event_name,
28+
std::optional<Value> data,
29+
std::optional<double> metric_value) {
30+
event_processor_->AsyncSend(events::TrackEventParams{
31+
std::chrono::system_clock::now(), std::move(event_name),
32+
context_.kinds_to_keys(), std::move(data), metric_value});
1233
}
13-
} // namespace launchdarkly
34+
35+
void Client::Track(std::string event_name, Value data, double metric_value) {
36+
this->TrackInternal(std::move(event_name), data, metric_value);
37+
}
38+
39+
void Client::Track(std::string event_name, Value data) {
40+
this->TrackInternal(std::move(event_name), data, std::nullopt);
41+
}
42+
43+
void Client::Track(std::string event_name) {
44+
this->TrackInternal(std::move(event_name), std::nullopt, std::nullopt);
45+
}
46+
47+
void Client::AsyncFlush() {
48+
event_processor_->AsyncFlush();
49+
}
50+
51+
void Client::AsyncIdentify(Context context) {
52+
event_processor_->AsyncSend(events::client::IdentifyEventParams{
53+
std::chrono::system_clock::now(), std::move(context)});
54+
}
55+
56+
bool Client::BoolVariation(Client::FlagKey const& key, bool default_value) {
57+
return default_value;
58+
}
59+
60+
std::string Client::StringVariation(Client::FlagKey const& key,
61+
std::string default_value) {
62+
return default_value;
63+
}
64+
65+
double Client::DoubleVariation(Client::FlagKey const& key,
66+
double default_value) {
67+
return default_value;
68+
}
69+
70+
int Client::IntVariation(Client::FlagKey const& key, int default_value) {
71+
return default_value;
72+
}
73+
74+
Value Client::JsonVariation(Client::FlagKey const& key, Value default_value) {
75+
return default_value;
76+
}
77+
78+
} // namespace launchdarkly::client_side

libs/client-sdk/tests/client_test.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <gtest/gtest.h>
2+
#include <launchdarkly/client_side/api.hpp>
3+
#include "context_builder.hpp"
4+
using namespace launchdarkly;
5+
6+
TEST(ClientTest, ConstructClientWithConfig) {
7+
tl::expected<client::Config, Error> config =
8+
client::ConfigBuilder("sdk-123").build();
9+
10+
ASSERT_TRUE(config);
11+
12+
auto context = ContextBuilder().kind("cat", "shadow").build();
13+
14+
client_side::Client client(std::move(*config), context);
15+
16+
ASSERT_TRUE(client.AllFlags().empty());
17+
ASSERT_TRUE(client.BoolVariation("cat-food", true));
18+
}

libs/common/include/config/client.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace launchdarkly::client {
99

1010
using SDK = config::detail::ClientSDK;
1111

12+
using Defaults = config::detail::Defaults<SDK>;
1213
using ApplicationInfo = config::detail::ApplicationInfo;
1314
using Endpoints = config::detail::EndpointsBuilder<SDK>;
1415
using ConfigBuilder = config::detail::ConfigBuilder<SDK>;

libs/common/include/config/detail/config.hpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "config/detail/endpoints_builder.hpp"
55
#include "config/detail/events_builder.hpp"
66
#include "config/detail/http_properties.hpp"
7+
#include "logger.hpp"
78

89
namespace launchdarkly::config::detail {
910

@@ -14,20 +15,41 @@ namespace launchdarkly::config::detail {
1415
*/
1516
template <typename SDK>
1617
struct Config {
17-
std::string sdk_key;
18-
bool offline;
19-
detail::EndpointsBuilder<SDK> service_endpoints_builder;
20-
std::optional<std::string> application_tag;
21-
detail::EventsBuilder<SDK> events_builder;
22-
DataSourceConfig<SDK> data_source_config;
23-
detail::HttpProperties http_properties;
18+
public:
2419
Config(std::string sdk_key,
2520
bool offline,
26-
detail::EndpointsBuilder<SDK> service_endpoints_builder,
27-
detail::EventsBuilder<SDK> events_builder,
21+
launchdarkly::Logger logger,
22+
ServiceEndpoints endpoints,
23+
Events events,
2824
std::optional<std::string> application_tag,
2925
DataSourceConfig<SDK> data_source_config,
3026
detail::HttpProperties http_properties);
27+
28+
std::string const& sdk_key() const;
29+
30+
ServiceEndpoints const& service_endpoints() const;
31+
32+
Events const& events_config() const;
33+
34+
std::optional<std::string> const& application_tag() const;
35+
36+
DataSourceConfig<SDK> const& data_source_config() const;
37+
38+
HttpProperties const& http_properties() const;
39+
40+
bool offline() const;
41+
42+
Logger take_logger();
43+
44+
private:
45+
std::string sdk_key_;
46+
bool offline_;
47+
launchdarkly::Logger logger_;
48+
ServiceEndpoints service_endpoints_;
49+
std::optional<std::string> application_tag_;
50+
Events events_;
51+
DataSourceConfig<SDK> data_source_config_;
52+
detail::HttpProperties http_properties_;
3153
};
3254

3355
} // namespace launchdarkly::config::detail

libs/common/include/config/detail/config_builder.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
#include <optional>
44
#include <string>
5+
#include <tl/expected.hpp>
56
#include "config/detail/application_info.hpp"
67
#include "config/detail/config.hpp"
78
#include "config/detail/data_source_builder.hpp"
89
#include "config/detail/endpoints_builder.hpp"
910
#include "config/detail/events_builder.hpp"
1011
#include "config/detail/http_properties_builder.hpp"
12+
1113
#include "logger.hpp"
1214

1315
namespace launchdarkly::config::detail {
@@ -22,15 +24,14 @@ class ConfigBuilder {
2224
public:
2325
using EndpointsBuilder = detail::EndpointsBuilder<SDK>;
2426
using EventsBuilder = detail::EventsBuilder<SDK>;
25-
using ConfigType = detail::Config<SDK>;
27+
using ConfigResult = tl::expected<detail::Config<SDK>, Error>;
2628
using DataSourceBuilder = detail::DataSourceBuilder<SDK>;
2729
using HttpPropertiesBuilder = detail::HttpPropertiesBuilder<SDK>;
2830
/**
2931
* A minimal configuration consists of a LaunchDarkly SDK Key.
3032
* @param sdk_key SDK Key.
3133
*/
3234
ConfigBuilder(std::string sdk_key);
33-
3435
/**
3536
* To customize the endpoints the SDK uses for streaming, polling, and
3637
* events, pass in an EndpointsBuilder.
@@ -83,7 +84,7 @@ class ConfigBuilder {
8384
* Builds a Configuration, suitable for passing into an instance of Client.
8485
* @return
8586
*/
86-
ConfigType build(Logger& logger) const;
87+
ConfigResult build() const;
8788

8889
private:
8990
std::string sdk_key_;

libs/common/include/config/detail/defaults.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ struct Defaults<ClientSDK> {
5656
static DataSourceConfig<ClientSDK> data_source_config() {
5757
return {Defaults<AnySDK>::streaming_config(), false, false};
5858
}
59+
60+
static bool offline() { return Defaults<AnySDK>::offline(); }
5961
};
6062

6163
template <>
@@ -83,6 +85,8 @@ struct Defaults<ServerSDK> {
8385
static DataSourceConfig<ServerSDK> data_source_config() {
8486
return {Defaults<AnySDK>::streaming_config()};
8587
}
88+
89+
static bool offline() { return Defaults<AnySDK>::offline(); }
8690
};
8791

8892
} // namespace launchdarkly::config::detail

libs/common/include/config/detail/http_properties.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ class HttpProperties final {
2929
// TODO: Proxy.
3030
};
3131

32+
bool operator==(HttpProperties const& lhs, HttpProperties const& rhs);
33+
3234
} // namespace launchdarkly::config::detail

libs/common/include/config/server.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace launchdarkly::server {
99

1010
using SDK = config::detail::ServerSDK;
1111

12+
using Defaults = config::detail::Defaults<SDK>;
1213
using ApplicationInfo = config::detail::ApplicationInfo;
1314
using Endpoints = config::detail::EndpointsBuilder<SDK>;
1415
using ConfigBuilder = config::detail::ConfigBuilder<SDK>;

libs/common/include/error.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ enum class Error : std::uint32_t {
2020

2121
kConfig_Events_ZeroCapacity = 300,
2222

23+
kConfig_SDKKey_Empty = 400,
24+
2325
/* Client-side errors: 10000-19999 */
2426
/* Server-side errors: 20000-29999 */
2527

0 commit comments

Comments
 (0)