Skip to content

Commit 609dae4

Browse files
authored
Merge pull request #33 from stackify/feature/INV-316
Cleanup of async log posts and retry logic
2 parents 1bd1157 + a01713e commit 609dae4

File tree

3 files changed

+63
-99
lines changed

3 files changed

+63
-99
lines changed

Src/StackifyLib/Internal/Logs/LogClient.cs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
using System;
2-
using System.Collections.Concurrent;
1+
using Newtonsoft.Json;
2+
using StackifyLib.Models;
3+
using StackifyLib.Utils;
4+
using System;
35
using System.Collections.Generic;
46
using System.Linq;
57
using System.Net;
6-
using System.Text;
78
using System.Threading;
8-
using System.Threading.Tasks;
9-
//using System.Web.Configuration;
10-
using Newtonsoft.Json;
11-
using StackifyLib.Models;
12-
using StackifyLib.Utils;
139

1410
namespace StackifyLib.Internal.Logs
1511
{
@@ -295,7 +291,7 @@ private Models.LogMsgGroup CreateDefaultMsgGroup()
295291
}
296292

297293

298-
internal Task<HttpClient.StackifyWebResponse> SendLogsByGroups(LogMsg[] messages)
294+
internal HttpClient.StackifyWebResponse SendLogsByGroups(LogMsg[] messages)
299295
{
300296
try
301297
{
@@ -309,16 +305,12 @@ private Models.LogMsgGroup CreateDefaultMsgGroup()
309305

310306
if (_HttpClient.IsRecentError())
311307
{
312-
var tcs = new TaskCompletionSource<HttpClient.StackifyWebResponse>();
313-
tcs.SetResult(new HttpClient.StackifyWebResponse() { Exception = new Exception("Unable to send logs at this time due to recent error: " + (_HttpClient.LastErrorMessage ?? "")) });
314-
return tcs.Task;
308+
return new HttpClient.StackifyWebResponse() { Exception = new Exception("Unable to send logs at this time due to recent error: " + (_HttpClient.LastErrorMessage ?? "")) };
315309
}
316310

317311
if (!identified)
318312
{
319-
var tcs = new TaskCompletionSource<HttpClient.StackifyWebResponse>();
320-
tcs.SetResult(new HttpClient.StackifyWebResponse() { Exception = new Exception("Unable to send logs at this time. Unable to identify app") });
321-
return tcs.Task;
313+
return new HttpClient.StackifyWebResponse() { Exception = new Exception("Unable to send logs at this time. Unable to identify app") };
322314
}
323315

324316
var groups = SplitLogsToGroups(messages);
@@ -338,28 +330,23 @@ private Models.LogMsgGroup CreateDefaultMsgGroup()
338330
}
339331

340332
StackifyAPILogger.Log("Sending " + messages.Length.ToString() + " log messages via send multi groups");
341-
var task =
342-
_HttpClient.SendJsonAndGetResponseAsync(
333+
var response =
334+
_HttpClient.SendJsonAndGetResponse(
343335
urlToUse,
344336
jsonData, jsonData.Length > 5000);
345337

346-
347338
messages = null;
348339
groups = null;
349340

350-
return task;
341+
return response;
351342

352343
}
353344
catch (Exception ex)
354345
{
355346
Utils.StackifyAPILogger.Log(ex.ToString());
356347

357-
var tcs = new TaskCompletionSource<HttpClient.StackifyWebResponse>();
358-
tcs.SetResult(new HttpClient.StackifyWebResponse() { Exception = ex });
359-
return tcs.Task;
348+
return new HttpClient.StackifyWebResponse() { Exception = ex };
360349
}
361-
362-
return null;
363350
}
364351
}
365352
}

Src/StackifyLib/Internal/Logs/LogQueue.cs

Lines changed: 46 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using System;
1+
using StackifyLib.Models;
2+
using StackifyLib.Utils;
3+
using System;
4+
using System.Collections.Concurrent;
25
using System.Collections.Generic;
36
using System.Linq;
4-
using System.Collections.Concurrent;
5-
using System.Diagnostics;
67
using System.Threading.Tasks;
7-
using StackifyLib.Models;
8-
using StackifyLib.Utils;
98

109
#if NET451 || NET45 || NET40
1110
using System.Runtime.Remoting.Messaging;
@@ -298,19 +297,11 @@ private int FlushLoop()
298297

299298
bool keepGoing = false;
300299

301-
var tasks = new List<Task>();
302-
303300
int flushTimes = 0;
304301
//Keep flushing
305302
do
306303
{
307-
int count;
308-
var task = FlushOnceAsync(out count);
309-
310-
if (task != null)
311-
{
312-
tasks.Add(task);
313-
}
304+
int count = FlushOnce();
314305

315306
if (count >= 100)
316307
{
@@ -324,14 +315,6 @@ private int FlushLoop()
324315
processedCount += count;
325316
} while (keepGoing && flushTimes < 25);
326317

327-
328-
if (_StopRequested && tasks.Any())
329-
{
330-
StackifyLib.Utils.StackifyAPILogger.Log("Waiting to ensure final log send. Waiting on " + tasks.Count + " tasks");
331-
Task.WaitAll(tasks.ToArray(), 5000);
332-
StackifyLib.Utils.StackifyAPILogger.Log("Final log flush complete");
333-
}
334-
335318
_QueueTooBig = _MessageBuffer.Count < Logger.MaxLogBufferSize;
336319
}
337320
}
@@ -343,12 +326,12 @@ private int FlushLoop()
343326
return processedCount;
344327
}
345328

346-
private Task FlushOnceAsync(out int messageSize)
329+
private int FlushOnce()
347330
{
348331

349332
// StackifyLib.Utils.StackifyAPILogger.Log("Calling FlushOnceAsync");
350333

351-
messageSize = 0;
334+
int messageSize = 0;
352335
var chunk = new List<LogMsg>();
353336

354337
//we only want to do this once at a time but the actual send is done async
@@ -393,85 +376,44 @@ private Task FlushOnceAsync(out int messageSize)
393376

394377
if (chunk.Any())
395378
{
379+
var response = _LogClient.SendLogsByGroups(chunk.ToArray());
396380

397-
return _LogClient.SendLogsByGroups(chunk.ToArray()).ContinueWith((continuation) =>
381+
if (response != null && response.Exception != null)
398382
{
383+
Utils.StackifyAPILogger.Log("Requeueing log messages due to error: " + response.Exception.ToString(), true);
399384

400-
if (continuation.Exception != null)
385+
if (response.IsClientError())
401386
{
402-
Utils.StackifyAPILogger.Log("Requeueing log messages due to error: " + continuation.Exception.ToString(), true);
387+
Utils.StackifyAPILogger.Log("Not requeueing log messages due to client error: " + response.StatusCode, true);
403388
}
404-
405-
if (continuation.Result != null && continuation.Result.Exception != null)
406-
{
407-
Utils.StackifyAPILogger.Log("Requeueing log messages due to error: " + continuation.Result.Exception.ToString(), true);
408-
}
409-
410-
if (continuation.Exception != null ||
411-
(continuation.Result != null && continuation.Result.Exception != null))
389+
else
412390
{
413391
try
414392
{
415-
bool messagesSentTooManyTimes = false;
416-
417-
foreach (var item in chunk)
418-
{
419-
item.UploadErrors++;
420-
421-
// try to upload up to 10 times
422-
if (item.UploadErrors < 100)
423-
{
424-
_MessageBuffer.Enqueue(item);
425-
}
426-
else
427-
{
428-
messagesSentTooManyTimes = true;
429-
}
430-
}
393+
bool messagesSentTooManyTimes = EnqueueForRetransmission(chunk);
431394

432395
if (messagesSentTooManyTimes)
433396
{
434397
Utils.StackifyAPILogger.Log(
435398
"Some messages not queued again due to too many failures uploading");
436399
}
437-
438400
}
439401
catch (Exception ex2)
440402
{
441403
Utils.StackifyAPILogger.Log("Error trying to requeue messages " + ex2.ToString());
442404
}
443405
}
444-
});
406+
}
445407
}
446408
}
447409
catch (Exception ex)
448410
{
449411
Utils.StackifyAPILogger.Log(ex.ToString());
450412

451-
452-
//requeue the messages that errored trying to upload
453-
try
454-
{
455-
foreach (var item in chunk)
456-
{
457-
item.UploadErrors++;
458-
459-
// try to upload up to 10 times
460-
if (item.UploadErrors < 10)
461-
{
462-
_MessageBuffer.Enqueue(item);
463-
}
464-
}
465-
466-
}
467-
catch (Exception ex2)
468-
{
469-
Utils.StackifyAPILogger.Log(ex2.ToString());
470-
}
413+
EnqueueForRetransmission(chunk);
471414
}
472415

473-
474-
return null;
416+
return messageSize;
475417
}
476418

477419

@@ -506,5 +448,34 @@ public void Pause(bool isPaused)
506448
{
507449
_PauseUpload = isPaused;
508450
}
451+
452+
private bool EnqueueForRetransmission(List<LogMsg> chunk)
453+
{
454+
bool skippedMessage = false;
455+
456+
try
457+
{
458+
foreach (var item in chunk)
459+
{
460+
++item.UploadErrors;
461+
462+
// retry up to 5 times
463+
if (item.UploadErrors < 5)
464+
{
465+
_MessageBuffer.Enqueue(item);
466+
}
467+
else
468+
{
469+
skippedMessage = true;
470+
}
471+
}
472+
}
473+
catch (Exception e)
474+
{
475+
Utils.StackifyAPILogger.Log(e.ToString());
476+
}
477+
478+
return skippedMessage;
479+
}
509480
}
510481
}

Src/StackifyLib/Utils/HttpClient.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ public class StackifyWebResponse
7070
public string ResponseText { get; set; }
7171
public System.Net.HttpStatusCode StatusCode { get; set; }
7272
public Exception Exception { get; set; }
73+
74+
// return true if 4xx status code
75+
public bool IsClientError()
76+
{
77+
return (HttpStatusCode.BadRequest <= StatusCode) && (StatusCode < HttpStatusCode.InternalServerError);
78+
}
7379
}
7480

7581
static HttpClient()

0 commit comments

Comments
 (0)