Skip to content
This repository was archived by the owner on Dec 6, 2024. It is now read-only.

Commit 347f774

Browse files
authored
1.0.0 GA (#8)
1 parent c887468 commit 347f774

28 files changed

+1847
-209
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to the LaunchDarkly C server-side SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).
44

5+
## [1.0.0] - 2019-07-05
6+
### Added
7+
- LRU caching to prevent users being indexed multiple times
8+
### Fixed
9+
- The server HTTP response time parsing logic
10+
511
## [1.0.0-beta.4] - 2019-06-11
612
### Fixed
713
- Memory leak when evaluating flags with prerequisites

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ add_library(ldserverapidynamic SHARED ${SOURCES})
2929
set_property(TARGET ldserverapidynamic PROPERTY C_VISIBILITY_PRESET hidden)
3030
target_link_libraries(ldserverapidynamic ${LD_LIBRARIES})
3131

32-
file(GLOB TESTS "tests/*")
32+
file(GLOB TESTS "tests/test-*")
3333
foreach(testsource ${TESTS})
3434
get_filename_component(testsourceleaf ${testsource} NAME)
3535
string(REPLACE ".c" "" testexe ${testsourceleaf})

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Contributing to the LaunchDarkly Server-side SDK for C/C++
1+
# Contributing to the LaunchDarkly Server-Side SDK for C/C++
22

33
LaunchDarkly has published an [SDK contributor's guide](https://docs.launchdarkly.com/docs/sdk-contributors-guide) that provides a detailed explanation of how our SDKs work. See below for additional information on how to contribute to this SDK.
44

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
1-
# LaunchDarkly Server-side SDK for C/C++
1+
# LaunchDarkly Server-Side SDK for C/C++
22

3-
The LaunchDarkly Server-side SDK for C/C++ is designed primarily for use in multi-user systems such as web servers and applications. It follows the server-side LaunchDarkly model for multi-user contexts. It is not intended for use in desktop and embedded systems applications.
3+
[![CircleCI](https://circleci.com/gh/launchdarkly/c-server-sdk.svg?style=svg)](https://circleci.com/gh/launchdarkly/c-server-sdk)
44

5-
For using LaunchDarkly in _client-side_ C/C++ applications, refer to our [Client-side C/C++ SDK](https://github.com/launchdarkly/c-client-sdk).
5+
The LaunchDarkly Server-Side SDK for C/C++ is designed primarily for use in multi-user systems such as web servers and applications. It follows the server-side LaunchDarkly model for multi-user contexts. It is not intended for use in desktop and embedded systems applications.
66

7-
*This version of the SDK is a **beta** version and should not be considered ready for production use while this message is visible.*
7+
For using LaunchDarkly in _client-side_ C/C++ applications, refer to our [client-side C/C++ SDK](https://github.com/launchdarkly/c-client-sdk).
88

99
## LaunchDarkly overview
1010

1111
[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/docs/getting-started) using LaunchDarkly today!
12-
12+
1313
[![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly)
14-
14+
1515
## Compatibility
16-
16+
1717
This version of the LaunchDarkly SDK is compatible with POSIX environments (Linux, OS X, BSD) and Windows.
18-
18+
1919
## Getting started
2020

2121
Download a release archive from the [GitHub Releases](https://github.com/launchdarkly/c-server-sdk/releases) for use in your project. Refer to the [SDK documentation](https://docs.launchdarkly.com/docs/c-server-sdk-reference#section-getting-started) for complete instructions on getting started with using the SDK.
22-
22+
2323
## Learn more
2424

2525
Check out our [documentation](https://docs.launchdarkly.com) for in-depth instructions on configuring and using LaunchDarkly. You can also head straight to the [complete reference guide for this SDK](https://docs.launchdarkly.com/docs/c-server-sdk-reference).
26-
26+
2727
## Testing
28-
28+
2929
We run integration tests for all our SDKs using a centralized test harness. This approach gives us the ability to test for consistency across SDKs, as well as test networking behavior in a long-running application. These tests cover each method in the SDK, and verify that event sending, flag evaluation, stream reconnection, and other aspects of the SDK all behave correctly.
30-
30+
3131
## Contributing
32-
32+
3333
We encourage pull requests and other contributions from the community. Check out our [contributing guidelines](CONTRIBUTING.md) for instructions on how to contribute to this SDK.
34-
34+
3535
## About LaunchDarkly
36-
36+
3737
* LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can:
3838
* Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases.
3939
* Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?).
@@ -45,4 +45,4 @@ We encourage pull requests and other contributions from the community. Check out
4545
* [docs.launchdarkly.com](https://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDK reference guides
4646
* [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation
4747
* [blog.launchdarkly.com](https://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates
48-
* [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies
48+
* [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies

include/launchdarkly/api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/** @brief The current SDK version string. This value adheres to semantic
99
* versioning and is included in the HTTP user agent sent to LaunchDarkly.
1010
*/
11-
#define LD_SDK_VERSION "1.0.0-beta.4"
11+
#define LD_SDK_VERSION "1.0.0"
1212

1313
#ifdef __cplusplus
1414
extern "C" {

include/launchdarkly/config.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,19 @@ LD_EXPORT(void) LDConfigSetUseLDD(struct LDConfig *const config,
157157
LD_EXPORT(void) LDConfigSetAllAttributesPrivate(struct LDConfig *const config,
158158
const bool allAttributesPrivate);
159159

160+
/**
161+
* @brief Set to true if you need to see the full user details in every
162+
* analytics event.
163+
* @param[in] config The configuration to modify. May not be `NULL` (assert).
164+
* @param[in] inlineUsersInEvents
165+
* @return Void
166+
*/
167+
LD_EXPORT(void) LDConfigInlineUsersInEvents(struct LDConfig *const config,
168+
const bool inlineUsersInEvents);
169+
160170
/**
161171
* @brief The number of user keys that the event processor can remember at an
162-
* one time, so that duplicate user details will not be sent in analytics..
172+
* one time, so that duplicate user details will not be sent in analytics.
163173
* @param[in] config The configuration to modify. May not be `NULL` (assert).
164174
* @param[in] userKeysCapacity
165175
* @return Void
@@ -175,7 +185,7 @@ LD_EXPORT(void) LDConfigSetUserKeysCapacity(struct LDConfig *const config,
175185
* @return Void
176186
*/
177187
LD_EXPORT(void) LDConfigSetUserKeysFlushInterval(struct LDConfig *const config,
178-
const unsigned int userKeysFlushInterval);
188+
const unsigned int milliseconds);
179189

180190
/**
181191
* @brief Marks a set of user attribute names private. Any users sent to

include/launchdarkly/memory.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include <launchdarkly/export.h>
99

10+
#include <stddef.h>
11+
1012
/** @brief Equivalent to `malloc` */
1113
LD_EXPORT(void *) LDAlloc(const size_t bytes);
1214
/** @brief Equivalent to `free` */

include/launchdarkly/variations.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ enum LDEvalErrorKind {
5656
LD_MALFORMED_FLAG,
5757
/** @brief Indicates that the result value was not of the requested type,
5858
* e.g. you called `LDBoolVariation` but the value was an integer. */
59-
LD_WRONG_TYPE
59+
LD_WRONG_TYPE,
60+
/** @brief Evaluation failed because the client ran out of memory */
61+
LD_OOM
6062
};
6163

6264
/** @brief Indicates which rule matched a user */

src/client.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "client.h"
1010
#include "config.h"
1111
#include "misc.h"
12+
#include "user.h"
1213

1314
struct LDClient *
1415
LDClientInit(struct LDConfig *const config, const unsigned int maxwaitmilli)
@@ -41,6 +42,8 @@ LDClientInit(struct LDConfig *const config, const unsigned int maxwaitmilli)
4142
client->summaryStart = 0;
4243
client->lastServerTime = 0;
4344

45+
LD_ASSERT(LDi_getMonotonicMilliseconds(&client->lastUserKeyFlush));
46+
4447
if (!LDi_rwlockinit(&client->lock)) {
4548
goto error;
4649
}
@@ -53,6 +56,10 @@ LDClientInit(struct LDConfig *const config, const unsigned int maxwaitmilli)
5356
goto error;
5457
}
5558

59+
if (!(client->userKeys = LDLRUInit(config->userKeysCapacity))) {
60+
goto error;
61+
}
62+
5663
if (!LDi_createthread(&client->thread, LDi_networkthread, client)) {
5764
goto error;
5865
}
@@ -86,6 +93,7 @@ LDClientInit(struct LDConfig *const config, const unsigned int maxwaitmilli)
8693

8794
LDJSONFree(client->events);
8895
LDJSONFree(client->summaryCounters);
96+
LDLRUFree(client->userKeys);
8997

9098
LDFree(client);
9199

@@ -108,6 +116,7 @@ LDClientClose(struct LDClient *const client)
108116
LD_ASSERT(LDi_rwlockdestroy(&client->lock));
109117
LDJSONFree(client->events);
110118
LDJSONFree(client->summaryCounters);
119+
LDLRUFree(client->userKeys);
111120

112121
if (client->config->defaultStore) {
113122
LDStoreDestroy(client->config->store);
@@ -129,25 +138,36 @@ LDClientIsInitialized(struct LDClient *const client)
129138
return LDStoreInitialized(client->config->store);
130139
}
131140

132-
133141
bool
134142
LDClientTrack(struct LDClient *const client, const char *const key,
135143
const struct LDUser *const user, struct LDJSON *const data)
136144
{
137-
struct LDJSON *event;
145+
struct LDJSON *event, *indexEvent;
138146

139147
LD_ASSERT(client);
140-
LD_ASSERT(user);
148+
LD_ASSERT(LDUserValidate(user));
141149
LD_ASSERT(key);
142150

151+
if (!LDi_maybeMakeIndexEvent(client, user, &indexEvent)) {
152+
LD_LOG(LD_LOG_ERROR, "failed to construct index event");
153+
154+
return false;
155+
}
156+
143157
if (!(event = LDi_newCustomEvent(client, user, key, data))) {
144158
LD_LOG(LD_LOG_ERROR, "failed to construct custom event");
145159

160+
LDJSONFree(indexEvent);
161+
146162
return false;
147163
}
148164

149165
LDi_addEvent(client, event);
150166

167+
if (indexEvent) {
168+
LDi_addEvent(client, indexEvent);
169+
}
170+
151171
return true;
152172
}
153173

@@ -157,7 +177,7 @@ LDClientIdentify(struct LDClient *const client, const struct LDUser *const user)
157177
struct LDJSON *event;
158178

159179
LD_ASSERT(client);
160-
LD_ASSERT(user);
180+
LD_ASSERT(LDUserValidate(user));
161181

162182
if (!(event = newIdentifyEvent(client, user))) {
163183
LD_LOG(LD_LOG_ERROR, "failed to construct identify event");

src/client.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <launchdarkly/api.h>
44

55
#include "misc.h"
6+
#include "lru.h"
67

78
struct LDClient {
89
bool initialized;
@@ -15,4 +16,6 @@ struct LDClient {
1516
unsigned long summaryStart;
1617
bool shouldFlush;
1718
unsigned long long lastServerTime;
19+
struct LDLRU *userKeys;
20+
unsigned long lastUserKeyFlush;
1821
};

0 commit comments

Comments
 (0)