async Task ConsumeQueue() { var buffer = new StructBuffer <Span[]>(bufferingCount); while (!cancellationTokenSource.IsCancellationRequested) { try { buffer.Clear(); var addCount = 0; for (int i = 0; i < bufferingCount; i++) { Span[] nextTrace; if (q.TryDequeue(out nextTrace)) { addCount++; buffer.Add(ref nextTrace); } else { break; } } if (addCount == 0) { await Task.Delay(bufferingTime).ConfigureAwait(false); } else { var traces = buffer.ToArray(); await client.Traces(traces).ConfigureAwait(false); } } catch (OperationCanceledException) { break; } catch (ObjectDisposedException) { break; } } }
async Task ConsumeQueue() { var buffer = new StructBuffer <Span[]>(bufferingCount); while (!cancellationTokenSource.IsCancellationRequested) { try { Task waiter = null; Span[][] singleTraces = null; Span[][] multipleTraces = null; lock (queueLock) { var rawEnqueuedArray = globalQueue.GetBuffer(); if (rawEnqueuedArray.Count == 0) { waiter = Task.Delay(bufferingTime, cancellationTokenSource.Token); } else if (rawEnqueuedArray.Count < bufferingCount) { singleTraces = new Span[rawEnqueuedArray.Count][]; Array.Copy(rawEnqueuedArray.Array, singleTraces, singleTraces.Length); globalQueue.ClearStrict(); } else { multipleTraces = new Span[rawEnqueuedArray.Count][]; Array.Copy(rawEnqueuedArray.Array, multipleTraces, multipleTraces.Length); globalQueue.ClearStrict(); } } if (waiter != null) { await waiter.ConfigureAwait(false); } else if (singleTraces != null) { // does not pass cancellation token. await client.Traces(singleTraces).ConfigureAwait(false); } else if (multipleTraces != null) { for (int i = 0; i < multipleTraces.Length;) { var tasks = new Task[Math.Min(ConcurrentRequestCountLimit, multipleTraces.Length - i)]; for (int j = 0; j < tasks.Length; j++) { var len = Math.Min(bufferingCount, multipleTraces.Length - i); if (len <= 0) { Array.Resize(ref tasks, j); break; } var segment = new ArraySegment <Span[]>(multipleTraces, i, len); i += len; tasks[j] = client.Traces(segment); } await Task.WhenAll(tasks).ConfigureAwait(false); } } } catch (TaskCanceledException) { } catch (OperationCanceledException) { await Task.Delay(bufferingTime, cancellationTokenSource.Token).ConfigureAwait(false); } catch (ObjectDisposedException) { await Task.Delay(bufferingTime, cancellationTokenSource.Token).ConfigureAwait(false); } catch (Exception ex) { logException(ex); await Task.Delay(bufferingTime, cancellationTokenSource.Token).ConfigureAwait(false); } } }
static void Main(string[] args) { var client = new DatadogSharp.Tracing.DatadogClient(); var rand = new Random(); var traces = new List <Span>(); //client.Services(new Service //{ // App = "myapp", // AppType = "web", // ServiceName = "high.throughput" //}).Wait(); var tid = Span.BuildRandomId(); Console.WriteLine(tid); var root = new DatadogSharp.Tracing.Span { TraceId = tid, SpanId = Span.BuildRandomId(), Name = "my_root", Resource = "/home", Service = "testservice", Start = Span.ToNanoseconds(DateTime.UtcNow), Type = "web", Duration = Span.ToNanoseconds(TimeSpan.FromMilliseconds(3500)), //Error = 1, //Meta = new Dictionary<string, string> { { "Message", new Exception().ToString() } } }; traces.Add(root); for (int i = 0; i < 4000; i++) { var test = new DatadogSharp.Tracing.Span { TraceId = tid, SpanId = Span.BuildRandomId(), Name = "my_test_span" + i, Resource = "/home", Service = "testservice", Start = Span.ToNanoseconds(DateTime.UtcNow.AddMilliseconds(rand.Next(0, 3000))), Type = "web", Duration = Span.ToNanoseconds(TimeSpan.FromMilliseconds(rand.Next(100, 300))), ParentId = root.SpanId }; traces.Add(test); } var bytes = MessagePackSerializer.Serialize(traces, DatadogSharpResolver.Instance); Console.WriteLine(MessagePackSerializer.ToJson(bytes)); var v = client.Traces(new[] { traces.ToArray() }).Result; Console.WriteLine(v); }