Skip to content

Commit 22f9262

Browse files
committed
refactor: tighten BigSegmentsBuilder defaults and docs
1 parent f1d32e3 commit 22f9262

3 files changed

Lines changed: 43 additions & 52 deletions

File tree

libs/server-sdk/src/config/builders/big_segments_builder.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
#include "big_segments_builder.hpp"
22

33
#include <algorithm>
4+
#include <chrono>
45
#include <utility>
56

67
namespace launchdarkly::server_side::config::builders {
78

9+
namespace {
10+
11+
using namespace std::chrono_literals;
12+
13+
constexpr std::size_t kDefaultContextCacheSize = 1000;
14+
constexpr std::chrono::milliseconds kDefaultContextCacheTime = 5s;
15+
constexpr std::chrono::milliseconds kDefaultStatusPollInterval = 5s;
16+
constexpr std::chrono::milliseconds kDefaultStaleAfter = 2min;
17+
18+
} // namespace
19+
820
BigSegmentsBuilder::BigSegmentsBuilder(
921
std::shared_ptr<integrations::IBigSegmentStore> store)
1022
: store_(std::move(store)),

libs/server-sdk/src/config/builders/big_segments_builder.hpp

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,11 @@ namespace launchdarkly::server_side::config::builders {
1212
/**
1313
* @brief Configures the SDK's Big Segments behavior.
1414
*
15-
* A Big Segments store implementation is required at construction. The
16-
* tunables that control the SDK's Big Segments caching and staleness
17-
* detection have sensible defaults and can be overridden via the fluent
18-
* setters.
19-
*
20-
* Non-positive durations passed to a setter are coerced back to the
21-
* default for that field.
22-
*
2315
* Not thread-safe. Construct, configure, and call @ref Build on a single
2416
* thread; the resulting @ref built::BigSegmentsConfig is safe to share.
2517
*/
2618
class BigSegmentsBuilder {
2719
public:
28-
static constexpr std::size_t kDefaultContextCacheSize = 1000;
29-
static constexpr std::chrono::milliseconds kDefaultContextCacheTime{5000};
30-
static constexpr std::chrono::milliseconds kDefaultStatusPollInterval{5000};
31-
static constexpr std::chrono::milliseconds kDefaultStaleAfter{120000};
32-
3320
/**
3421
* @brief Constructs a builder for the given Big Segments store.
3522
*
@@ -41,7 +28,7 @@ class BigSegmentsBuilder {
4128

4229
/**
4330
* @brief Sets the maximum number of context membership lookups cached
44-
* by the SDK.
31+
* by the SDK. Defaults to 1000.
4532
*
4633
* To reduce store traffic, the SDK maintains an LRU cache keyed by
4734
* context key. A higher value reduces store queries for
@@ -50,40 +37,41 @@ class BigSegmentsBuilder {
5037
BigSegmentsBuilder& ContextCacheSize(std::size_t size);
5138

5239
/**
53-
* @brief Sets the time-to-live for cached membership lookups.
40+
* @brief Sets the time-to-live for cached membership lookups. Defaults
41+
* to 5 seconds.
5442
*
5543
* A higher value reduces store queries for any given context, but
5644
* delays the SDK noticing membership changes. Zero or negative
57-
* durations are coerced to @ref kDefaultContextCacheTime.
45+
* durations are coerced to the default.
5846
*/
5947
BigSegmentsBuilder& ContextCacheTime(std::chrono::milliseconds ttl);
6048

6149
/**
6250
* @brief Sets the interval at which the SDK polls the store's metadata
63-
* to determine availability and staleness.
51+
* to determine availability and staleness. Defaults to 5 seconds.
6452
*
65-
* Zero or negative durations are coerced to
66-
* @ref kDefaultStatusPollInterval.
53+
* Zero or negative durations are coerced to the default.
6754
*/
6855
BigSegmentsBuilder& StatusPollInterval(std::chrono::milliseconds interval);
6956

7057
/**
7158
* @brief Sets how long the SDK waits before treating store data as
72-
* stale.
59+
* stale. Defaults to 2 minutes.
7360
*
7461
* If the store's last-updated timestamp falls behind the current time
7562
* by more than this duration, evaluations report a big segments status
7663
* of `STALE` and the status provider reports the store as stale. Zero
77-
* or negative durations are coerced to @ref kDefaultStaleAfter.
64+
* or negative durations are coerced to the default.
7865
*/
7966
BigSegmentsBuilder& StaleAfter(std::chrono::milliseconds threshold);
8067

8168
/**
8269
* @brief Resolves the configuration.
8370
*
8471
* If the configured @ref StatusPollInterval exceeds @ref StaleAfter,
85-
* the poll interval is clamped to the stale-after value so the SDK can
86-
* detect staleness within one poll cycle (per BIGSEG §1.4.6).
72+
* the poll interval in the returned config is clamped to the
73+
* stale-after value so the SDK can detect staleness within one poll
74+
* cycle.
8775
*/
8876
[[nodiscard]] built::BigSegmentsConfig Build() const;
8977

libs/server-sdk/tests/big_segments_builder_test.cpp

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ using launchdarkly::server_side::integrations::StoreMetadata;
1515

1616
namespace {
1717

18+
using namespace std::chrono_literals;
19+
1820
// Minimal stub used only to obtain a shared_ptr<IBigSegmentStore>. The builder
1921
// never invokes the store; it only stores the pointer for later use by the
2022
// wrapper, so the methods here are unreachable in these tests.
@@ -39,13 +41,10 @@ TEST(BigSegmentsBuilderTest, DefaultsMatchSpec) {
3941
auto store = MakeStubStore();
4042
auto const cfg = BigSegmentsBuilder(store).Build();
4143

42-
EXPECT_EQ(cfg.context_cache_size,
43-
BigSegmentsBuilder::kDefaultContextCacheSize);
44-
EXPECT_EQ(cfg.context_cache_time,
45-
BigSegmentsBuilder::kDefaultContextCacheTime);
46-
EXPECT_EQ(cfg.status_poll_interval,
47-
BigSegmentsBuilder::kDefaultStatusPollInterval);
48-
EXPECT_EQ(cfg.stale_after, BigSegmentsBuilder::kDefaultStaleAfter);
44+
EXPECT_EQ(cfg.context_cache_size, 1000u);
45+
EXPECT_EQ(cfg.context_cache_time, 5s);
46+
EXPECT_EQ(cfg.status_poll_interval, 5s);
47+
EXPECT_EQ(cfg.stale_after, 2min);
4948
}
5049

5150
TEST(BigSegmentsBuilderTest, BuildPreservesStoreIdentity) {
@@ -62,7 +61,6 @@ TEST(BigSegmentsBuilderTest, AcceptsNullStore) {
6261
}
6362

6463
TEST(BigSegmentsBuilderTest, SettersOverrideEachField) {
65-
using namespace std::chrono_literals;
6664
auto store = MakeStubStore();
6765
auto const cfg = BigSegmentsBuilder(store)
6866
.ContextCacheSize(7)
@@ -80,37 +78,32 @@ TEST(BigSegmentsBuilderTest, SettersOverrideEachField) {
8078
TEST(BigSegmentsBuilderTest, ZeroDurationsAreCoercedToDefaults) {
8179
auto store = MakeStubStore();
8280
auto const cfg = BigSegmentsBuilder(store)
83-
.ContextCacheTime(std::chrono::milliseconds::zero())
84-
.StatusPollInterval(std::chrono::milliseconds::zero())
85-
.StaleAfter(std::chrono::milliseconds::zero())
81+
.ContextCacheTime(0ms)
82+
.StatusPollInterval(0ms)
83+
.StaleAfter(0ms)
8684
.Build();
8785

88-
EXPECT_EQ(cfg.context_cache_time,
89-
BigSegmentsBuilder::kDefaultContextCacheTime);
90-
EXPECT_EQ(cfg.status_poll_interval,
91-
BigSegmentsBuilder::kDefaultStatusPollInterval);
92-
EXPECT_EQ(cfg.stale_after, BigSegmentsBuilder::kDefaultStaleAfter);
86+
EXPECT_EQ(cfg.context_cache_time, 5s);
87+
EXPECT_EQ(cfg.status_poll_interval, 5s);
88+
EXPECT_EQ(cfg.stale_after, 2min);
9389
}
9490

9591
TEST(BigSegmentsBuilderTest, NegativeDurationsAreCoercedToDefaults) {
9692
auto store = MakeStubStore();
9793
auto const cfg = BigSegmentsBuilder(store)
98-
.ContextCacheTime(std::chrono::milliseconds{-1})
99-
.StatusPollInterval(std::chrono::milliseconds{-1})
100-
.StaleAfter(std::chrono::milliseconds{-1})
94+
.ContextCacheTime(-1ms)
95+
.StatusPollInterval(-1ms)
96+
.StaleAfter(-1ms)
10197
.Build();
10298

103-
EXPECT_EQ(cfg.context_cache_time,
104-
BigSegmentsBuilder::kDefaultContextCacheTime);
105-
EXPECT_EQ(cfg.status_poll_interval,
106-
BigSegmentsBuilder::kDefaultStatusPollInterval);
107-
EXPECT_EQ(cfg.stale_after, BigSegmentsBuilder::kDefaultStaleAfter);
99+
EXPECT_EQ(cfg.context_cache_time, 5s);
100+
EXPECT_EQ(cfg.status_poll_interval, 5s);
101+
EXPECT_EQ(cfg.stale_after, 2min);
108102
}
109103

110104
TEST(BigSegmentsBuilderTest, BuildClampsPollIntervalToStaleAfter) {
111-
// BIGSEG §1.4.6: when poll interval > stale-after, clamp poll to
112-
// stale-after so the SDK detects staleness within one poll cycle.
113-
using namespace std::chrono_literals;
105+
// When poll interval > stale-after, clamp poll to stale-after so the
106+
// SDK detects staleness within one poll cycle.
114107
auto store = MakeStubStore();
115108
auto const cfg = BigSegmentsBuilder(store)
116109
.StatusPollInterval(10s)
@@ -122,7 +115,6 @@ TEST(BigSegmentsBuilderTest, BuildClampsPollIntervalToStaleAfter) {
122115
}
123116

124117
TEST(BigSegmentsBuilderTest, BuildPreservesPollIntervalWhenWithinStaleAfter) {
125-
using namespace std::chrono_literals;
126118
auto store = MakeStubStore();
127119
auto const cfg = BigSegmentsBuilder(store)
128120
.StatusPollInterval(3s)
@@ -134,7 +126,6 @@ TEST(BigSegmentsBuilderTest, BuildPreservesPollIntervalWhenWithinStaleAfter) {
134126
}
135127

136128
TEST(BigSegmentsBuilderTest, BuildIsRepeatable) {
137-
using namespace std::chrono_literals;
138129
auto store = MakeStubStore();
139130
BigSegmentsBuilder builder(store);
140131
builder.ContextCacheSize(42).ContextCacheTime(2s);

0 commit comments

Comments
 (0)