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

Commit 660f4df

Browse files
prepare 2.3.0 release (#27)
1 parent da0d417 commit 660f4df

File tree

6 files changed

+243
-0
lines changed

6 files changed

+243
-0
lines changed

include/launchdarkly/client.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@ LD_EXPORT(LDBoolean) LDClientTrackMetric(struct LDClient *const client,
7777
const char *const key, const struct LDUser *const user,
7878
struct LDJSON *const data, const double metric);
7979

80+
/**
81+
* @brief Record a alias event
82+
* @param[in] client The client to use. May not be `NULL`.
83+
* @param[in] currentUser The new version of a user. Ownership is not
84+
* transferred. May not be `NULL`.
85+
* @param[in] previousUser The previous version of a user. Ownership is not
86+
* transferred. May not be `NULL`.
87+
* @return True if the event was queued, False on error.
88+
*/
89+
LD_EXPORT(LDBoolean) LDClientAlias(struct LDClient *const client,
90+
const struct LDUser *const currentUser,
91+
const struct LDUser *const previousUser);
92+
8093
/**
8194
* @brief Generates an identify event for a user.
8295
* @param[in] client The client to use. May not be `NULL`.

src/client.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,39 @@ LDClientTrackMetric(struct LDClient *const client, const char *const key,
185185
return LDi_track(client->eventProcessor, user, key, data, metric, true);
186186
}
187187

188+
LDBoolean
189+
LDClientAlias(
190+
struct LDClient *const client,
191+
const struct LDUser *const currentUser,
192+
const struct LDUser *const previousUser
193+
) {
194+
LD_ASSERT_API(client);
195+
LD_ASSERT_API(currentUser);
196+
LD_ASSERT_API(previousUser);
197+
198+
#ifdef LAUNCHDARKLY_DEFENSIVE
199+
if (client == NULL) {
200+
LD_LOG(LD_LOG_WARNING, "LDClientAlias NULL client");
201+
202+
return 0;
203+
}
204+
205+
if (currentUser == NULL) {
206+
LD_LOG(LD_LOG_WARNING, "LDClientAlias NULL currentUser");
207+
208+
return 0;
209+
}
210+
211+
if (previousUser == NULL) {
212+
LD_LOG(LD_LOG_WARNING, "LDClientAlias NULL previousUser");
213+
214+
return 0;
215+
}
216+
#endif
217+
218+
return LDi_alias(client->eventProcessor, currentUser, previousUser);
219+
}
220+
188221
LDBoolean
189222
LDClientIdentify(struct LDClient *const client, const struct LDUser *const user)
190223
{

src/event_processor.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,18 @@ LDi_newFeatureRequestEvent(
840840
}
841841
}
842842

843+
if (user->anonymous) {
844+
if (!(tmp = LDNewText("anonymousUser"))) {
845+
goto error;
846+
}
847+
848+
if (!LDObjectSetKey(event, "contextKind", tmp)) {
849+
LDJSONFree(tmp);
850+
851+
goto error;
852+
}
853+
}
854+
843855
return event;
844856

845857
error:
@@ -1172,6 +1184,18 @@ LDi_newCustomEvent(
11721184
}
11731185
}
11741186

1187+
if (user->anonymous) {
1188+
if (!(tmp = LDNewText("anonymousUser"))) {
1189+
goto error;
1190+
}
1191+
1192+
if (!LDObjectSetKey(event, "contextKind", tmp)) {
1193+
LDJSONFree(tmp);
1194+
1195+
goto error;
1196+
}
1197+
}
1198+
11751199
return event;
11761200

11771201
error:
@@ -1372,6 +1396,103 @@ LDi_track(
13721396
return true;
13731397
}
13741398

1399+
static struct LDJSON *
1400+
contextKindString(const struct LDUser *const user)
1401+
{
1402+
if (user->anonymous) {
1403+
return LDNewText("anonymousUser");
1404+
} else {
1405+
return LDNewText("user");
1406+
}
1407+
}
1408+
1409+
struct LDJSON *
1410+
LDi_newAliasEvent(
1411+
const struct LDUser *const currentUser,
1412+
const struct LDUser *const previousUser,
1413+
const double now
1414+
) {
1415+
struct LDJSON *tmp, *event;
1416+
1417+
LD_ASSERT(currentUser);
1418+
LD_ASSERT(previousUser);
1419+
1420+
tmp = NULL;
1421+
event = NULL;
1422+
1423+
if (!(event = LDi_newBaseEvent("alias", now))) {
1424+
goto error;
1425+
}
1426+
1427+
if (!(tmp = LDNewText(currentUser->key))) {
1428+
goto error;
1429+
}
1430+
1431+
if (!LDObjectSetKey(event, "key", tmp)) {
1432+
goto error;
1433+
}
1434+
1435+
if (!(tmp = LDNewText(previousUser->key))) {
1436+
goto error;
1437+
}
1438+
1439+
if (!LDObjectSetKey(event, "previousKey", tmp)) {
1440+
goto error;
1441+
}
1442+
1443+
if (!(tmp = contextKindString(currentUser))) {
1444+
goto error;
1445+
}
1446+
1447+
if (!LDObjectSetKey(event, "contextKind", tmp)) {
1448+
goto error;
1449+
}
1450+
1451+
if (!(tmp = contextKindString(previousUser))) {
1452+
goto error;
1453+
}
1454+
1455+
if (!LDObjectSetKey(event, "previousContextKind", tmp)) {
1456+
goto error;
1457+
}
1458+
1459+
return event;
1460+
1461+
error:
1462+
LDJSONFree(event);
1463+
LDJSONFree(tmp);
1464+
1465+
return NULL;
1466+
}
1467+
1468+
LDBoolean
1469+
LDi_alias(
1470+
struct EventProcessor *const context,
1471+
const struct LDUser *const currentUser,
1472+
const struct LDUser *const previousUser
1473+
) {
1474+
struct LDJSON *event;
1475+
double now;
1476+
1477+
LD_ASSERT(context);
1478+
LD_ASSERT(currentUser);
1479+
LD_ASSERT(previousUser);
1480+
1481+
LDi_getUnixMilliseconds(&now);
1482+
1483+
if (!(event = LDi_newAliasEvent(currentUser, previousUser, now))) {
1484+
LD_LOG(LD_LOG_ERROR, "failed to construct alias event");
1485+
1486+
return 0;
1487+
}
1488+
1489+
LDi_mutex_lock(&context->lock);
1490+
LDi_addEvent(context, event);
1491+
LDi_mutex_unlock(&context->lock);
1492+
1493+
return 1;
1494+
}
1495+
13751496
bool
13761497
LDi_bundleEventPayload(
13771498
struct EventProcessor *const context,

src/event_processor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <launchdarkly/boolean.h>
34
#include <launchdarkly/json.h>
45
#include <launchdarkly/variations.h>
56

@@ -34,6 +35,13 @@ LDi_track(
3435
const bool hasMetric
3536
);
3637

38+
LDBoolean
39+
LDi_alias(
40+
struct EventProcessor *const context,
41+
const struct LDUser *const currentUser,
42+
const struct LDUser *const previousUser
43+
);
44+
3745
bool
3846
LDi_processEvaluation(
3947
/* required */

src/event_processor_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ LDi_newCustomEvent(
6464
const double now
6565
);
6666

67+
struct LDJSON *
68+
LDi_newAliasEvent(
69+
const struct LDUser *const currentUser,
70+
const struct LDUser *const previousUser,
71+
const double now
72+
);
73+
6774
void
6875
LDi_possiblyQueueEvent(
6976
struct EventProcessor *const context,

tests/test-event-processor.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,65 @@ testExperimentationRuleNonDetailed()
534534
LDClientClose(client);
535535
}
536536

537+
static void
538+
testConstructAliasEvent()
539+
{
540+
struct LDUser *previous, *current;
541+
struct LDJSON *result, *expected;
542+
543+
LD_ASSERT(previous = LDUserNew("a"));
544+
LD_ASSERT(current = LDUserNew("b"));
545+
546+
LDUserSetAnonymous(previous, true);
547+
548+
LD_ASSERT(result = LDi_newAliasEvent(current, previous, 52));
549+
550+
LD_ASSERT(expected = LDNewObject());
551+
LD_ASSERT(LDObjectSetKey(expected, "kind", LDNewText("alias")));
552+
LD_ASSERT(LDObjectSetKey(expected, "creationDate", LDNewNumber(52)));
553+
LD_ASSERT(LDObjectSetKey(expected, "key", LDNewText("b")));
554+
LD_ASSERT(LDObjectSetKey(expected, "contextKind", LDNewText("user")));
555+
LD_ASSERT(LDObjectSetKey(expected, "previousKey", LDNewText("a")));
556+
LD_ASSERT(LDObjectSetKey(expected, "previousContextKind",
557+
LDNewText("anonymousUser")));
558+
559+
LD_ASSERT(LDJSONCompare(result, expected));
560+
561+
LDJSONFree(expected);
562+
LDJSONFree(result);
563+
LDUserFree(previous);
564+
LDUserFree(current);
565+
}
566+
567+
static void
568+
testAliasEventIsQueued()
569+
{
570+
struct LDClient *client;
571+
double metricValue;
572+
const char *metricName;
573+
struct LDJSON *payload, *event;
574+
struct LDUser *previous, *current;
575+
576+
LD_ASSERT(previous = LDUserNew("p"));
577+
LD_ASSERT(current = LDUserNew("c"));
578+
579+
LD_ASSERT(client = makeOfflineClient());
580+
581+
LDClientAlias(client, current, previous);
582+
583+
LD_ASSERT(LDi_bundleEventPayload(client->eventProcessor, &payload))
584+
585+
LD_ASSERT(LDCollectionGetSize(payload) == 1);
586+
LD_ASSERT(event = LDArrayLookup(payload, 0));
587+
LD_ASSERT(strcmp("alias", LDGetText(LDObjectLookup(event, "kind"))) == 0);
588+
589+
LDUserFree(previous);
590+
LDUserFree(current);
591+
LDJSONFree(payload);
592+
593+
LDClientClose(client);
594+
}
595+
537596
int
538597
main()
539598
{
@@ -553,6 +612,8 @@ main()
553612
testDetailsIncludedIfDetailed();
554613
testExperimentationFallthroughNonDetailed();
555614
testExperimentationRuleNonDetailed();
615+
testConstructAliasEvent();
616+
testAliasEventIsQueued();
556617

557618
LDBasicLoggerThreadSafeShutdown();
558619

0 commit comments

Comments
 (0)