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

Commit 76b3a40

Browse files
prepare 1.2.1 release (#16)
1 parent 48cd1c1 commit 76b3a40

File tree

6 files changed

+183
-114
lines changed

6 files changed

+183
-114
lines changed

src/events.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ struct AnalyticsContext {
868868
struct curl_slist *headers;
869869
struct LDClient *client;
870870
char *buffer;
871-
bool lastFailed;
871+
unsigned int failureTime;
872872
char payloadId[LD_UUID_SIZE + 1];
873873
};
874874

@@ -882,31 +882,54 @@ resetMemory(struct AnalyticsContext *const context)
882882

883883
LDFree(context->buffer);
884884
context->buffer = NULL;
885+
886+
context->failureTime = 0;
885887
}
886888

887889
static void
888-
done(struct LDClient *const client, void *const rawcontext, const bool success)
890+
done(struct LDClient *const client, void *const rawcontext,
891+
const int responseCode)
889892
{
890893
struct AnalyticsContext *context;
894+
const bool success = responseCode == 200 || responseCode == 202;
891895

892896
LD_ASSERT(client);
893897
LD_ASSERT(rawcontext);
894898

895899
context = (struct AnalyticsContext *)rawcontext;
896900

897-
LD_LOG(LD_LOG_INFO, "done!");
901+
context->active = false;
898902

899-
context->active = false;
900-
context->lastFailed = !success;
903+
LD_LOG(LD_LOG_TRACE, "events network interface called done");
901904

902905
if (success) {
906+
LD_LOG(LD_LOG_TRACE, "event batch send successful");
907+
903908
LD_ASSERT(LDi_wrlock(&client->lock));
904909
client->shouldFlush = false;
905910
LD_ASSERT(LDi_wrunlock(&client->lock));
906911

907912
LD_ASSERT(LDi_getMonotonicMilliseconds(&context->lastFlush));
908913

909914
resetMemory(context);
915+
} else {
916+
unsigned long now;
917+
918+
/* failed twice so just discard the payload */
919+
if (context->failureTime) {
920+
LD_LOG(LD_LOG_ERROR, "failed sending events twice, discarding");
921+
922+
resetMemory(context);
923+
} else {
924+
LD_LOG(LD_LOG_WARNING, "failed sending events, retrying");
925+
/* setup waiting and retry logic */
926+
LD_ASSERT(LDi_getMonotonicMilliseconds(&now));
927+
928+
context->failureTime = now;
929+
930+
curl_slist_free_all(context->headers);
931+
context->headers = NULL;
932+
}
910933
}
911934
}
912935

@@ -1166,6 +1189,7 @@ poll(struct LDClient *const client, void *const rawcontext)
11661189
const char *mime, *schema;
11671190
bool shouldFlush;
11681191
struct LDJSON *summaryEvent;
1192+
bool lastFailed;
11691193

11701194
LD_ASSERT(rawcontext);
11711195

@@ -1174,14 +1198,26 @@ poll(struct LDClient *const client, void *const rawcontext)
11741198
mime = "Content-Type: application/json";
11751199
schema = "X-LaunchDarkly-Event-Schema: 3";
11761200
context = (struct AnalyticsContext *)rawcontext;
1201+
lastFailed = context->failureTime != 0;
11771202

11781203
/* decide if events should be sent */
11791204

11801205
if (context->active) {
11811206
return NULL;
11821207
}
11831208

1184-
if (!context->lastFailed) {
1209+
if (context->failureTime) {
1210+
unsigned long now;
1211+
1212+
LD_ASSERT(LDi_getMonotonicMilliseconds(&now));
1213+
1214+
/* wait for one second before retrying send */
1215+
if (now <= context->failureTime + 1000) {
1216+
return NULL;
1217+
}
1218+
}
1219+
1220+
if (!lastFailed) {
11851221
struct LDJSON *nextEvents, *nextSummaryCounters;
11861222

11871223
nextEvents = NULL;
@@ -1387,21 +1423,19 @@ LDi_constructAnalytics(struct LDClient *const client)
13871423
goto error;
13881424
}
13891425

1390-
context->active = false;
1391-
context->headers = NULL;
1392-
context->client = client;
1393-
context->buffer = NULL;
1394-
context->lastFailed = false;
1426+
context->active = false;
1427+
context->headers = NULL;
1428+
context->client = client;
1429+
context->buffer = NULL;
1430+
context->failureTime = 0;
13951431

13961432
LD_ASSERT(LDi_getMonotonicMilliseconds(&context->lastFlush));
13971433

1398-
netInterface->done = done;
1399-
netInterface->poll = poll;
1400-
netInterface->context = context;
1401-
netInterface->destroy = destroy;
1402-
netInterface->current = NULL;
1403-
netInterface->attempts = 0;
1404-
netInterface->waitUntil = 0;
1434+
netInterface->done = done;
1435+
netInterface->poll = poll;
1436+
netInterface->context = context;
1437+
netInterface->destroy = destroy;
1438+
netInterface->current = NULL;
14051439

14061440
return netInterface;
14071441

src/net.c

Lines changed: 6 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -145,55 +145,6 @@ LDi_networkthread(void* const clientref)
145145
if (!offline) {
146146
for (i = 0; i < interfacecount; i++) {
147147
CURL *handle;
148-
/* skip if waiting on backoff */
149-
if (interfaces[i]->attempts) {
150-
unsigned long now;
151-
152-
if (!LDi_getMonotonicMilliseconds(&now)) {
153-
LD_LOG(LD_LOG_ERROR, "failed to get time for backoff");
154-
155-
goto cleanup;
156-
}
157-
158-
if (interfaces[i]->waitUntil) {
159-
if (now >= interfaces[i]->waitUntil) {
160-
interfaces[i]->waitUntil = 0;
161-
/* fallthrough to polling */
162-
} else {
163-
/* still waiting on this interface */
164-
continue;
165-
}
166-
} else {
167-
double backoff;
168-
unsigned int rng;
169-
170-
/* random value for jitter */
171-
if (!LDi_random(&rng)) {
172-
LD_LOG(LD_LOG_ERROR,
173-
"failed to get rng for jitter calculation");
174-
175-
goto cleanup;
176-
}
177-
178-
/* calculate time to wait */
179-
backoff = 1000 * pow(2, interfaces[i]->attempts) / 2;
180-
181-
/* cap (min not built in) */
182-
if (backoff > 3600 * 1000) {
183-
backoff = 3600 * 1000;
184-
}
185-
186-
/* jitter */
187-
backoff /= 2;
188-
189-
backoff = backoff +
190-
LDi_normalize(rng, 0, LD_RAND_MAX, 0, backoff);
191-
192-
interfaces[i]->waitUntil = now + backoff;
193-
/* skip because we are waiting */
194-
continue;
195-
}
196-
}
197148

198149
/* not waiting on backoff */
199150
handle = interfaces[i]->poll(client, interfaces[i]->context);
@@ -226,20 +177,19 @@ LDi_networkthread(void* const clientref)
226177
info = curl_multi_info_read(multihandle, &inqueue);
227178

228179
if (info && (info->msg == CURLMSG_DONE)) {
229-
long responsecode;
180+
long responseCode;
230181
CURL *easy = info->easy_handle;
231182
struct NetworkInterface *netInterface = NULL;
232-
bool requestSuccess;
233183

234184
if (curl_easy_getinfo(
235-
easy, CURLINFO_RESPONSE_CODE, &responsecode) != CURLE_OK)
185+
easy, CURLINFO_RESPONSE_CODE, &responseCode) != CURLE_OK)
236186
{
237187
LD_LOG(LD_LOG_ERROR, "failed to get response code");
238188

239189
goto cleanup;
240190
}
241191

242-
if (responsecode == 401 || responsecode == 403) {
192+
if (responseCode == 401 || responseCode == 403) {
243193
LD_LOG(LD_LOG_ERROR, "LaunchDarkly API Access Denied");
244194

245195
goto cleanup;
@@ -251,7 +201,7 @@ LDi_networkthread(void* const clientref)
251201
LD_ASSERT(snprintf(msg, sizeof(msg),
252202
"message done code %s %ld",
253203
curl_easy_strerror(info->data.result),
254-
responsecode) >= 0);
204+
responseCode) >= 0);
255205

256206
LD_LOG(LD_LOG_TRACE, msg);
257207
}
@@ -268,16 +218,8 @@ LDi_networkthread(void* const clientref)
268218
LD_ASSERT(netInterface->done);
269219
LD_ASSERT(netInterface->context);
270220

271-
requestSuccess = info->data.result == CURLE_OK &&
272-
(responsecode == 200 || responsecode == 202);
273-
274-
if (requestSuccess) {
275-
netInterface->attempts = 0;
276-
} else {
277-
netInterface->attempts++;
278-
}
279-
280-
netInterface->done(client, netInterface->context, requestSuccess);
221+
netInterface->done(client, netInterface->context,
222+
info->data.result == CURLE_OK ? responseCode : 0);
281223

282224
netInterface->current = NULL;
283225

src/network.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,13 @@ struct NetworkInterface {
1313
/* get next handle */
1414
CURL *(*poll)(struct LDClient *const client, void *context);
1515
/* called when handle is ready */
16-
void (*done)(struct LDClient *const client, void *context, bool success);
16+
void (*done)(struct LDClient *const client, void *context, int responseCode);
1717
/* final action destroy */
1818
void (*destroy)(void *context);
1919
/* stores any private implementation data */
2020
void *context;
2121
/* active handle */
2222
CURL *current;
23-
/* used for tracking retry */
24-
unsigned int attempts;
25-
/* point in future to backoff until */
26-
unsigned long waitUntil;
2723
};
2824

2925
bool LDi_prepareShared(const struct LDConfig *const config,

src/polling.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@ resetMemory(struct PollContext *const context)
9999
}
100100

101101
static void
102-
done(struct LDClient *const client, void *const rawcontext, const bool success)
102+
done(struct LDClient *const client, void *const rawcontext,
103+
const int responseCode)
103104
{
104105
struct PollContext *context;
106+
const bool success = responseCode == 200;
105107

106108
LD_ASSERT(client);
107109
LD_ASSERT(rawcontext);
@@ -242,14 +244,12 @@ LDi_constructPolling(struct LDClient *const client)
242244
context->active = false;
243245
context->lastpoll = 0;
244246

245-
netInterface->done = done;
246-
netInterface->poll = poll;
247-
netInterface->context = context;
248-
netInterface->destroy = destroy;
249-
netInterface->context = context;
250-
netInterface->current = NULL;
251-
netInterface->attempts = 0;
252-
netInterface->waitUntil = 0;
247+
netInterface->done = done;
248+
netInterface->poll = poll;
249+
netInterface->context = context;
250+
netInterface->destroy = destroy;
251+
netInterface->context = context;
252+
netInterface->current = NULL;
253253

254254
return netInterface;
255255

0 commit comments

Comments
 (0)