예제 #1
0
        public AsyncQueueWorker(DatadogClient client, int bufferingCount = 10, int bufferingTimeMilliseconds = 5000, Action <Exception> logException = null)
        {
            this.globalQueue    = new StructBuffer <Span[]>(16);
            this.client         = client;
            this.logException   = logException ?? ((Exception ex) => { });
            this.bufferingCount = bufferingCount;
            this.bufferingTime  = TimeSpan.FromMilliseconds(bufferingTimeMilliseconds);

            // Start
            this.processingTask = Task.Factory.StartNew(ConsumeQueue, TaskCreationOptions.LongRunning).Unwrap();
        }
예제 #2
0
 public TracingScope(string name, string resource, string service, string type, TracingManager manager, ulong traceId, ulong?parentId)
 {
     this.Name     = name;
     this.Resource = resource;
     this.Service  = service;
     this.Type     = type;
     this.TraceId  = traceId;
     this.SpanId   = Span.BuildRandomId();
     this.start    = Span.ToNanoseconds(DateTime.UtcNow);
     this.duration = ThreadSafeUtil.RentStopwatchStartNew();
     this.manager  = manager;
     this.spans    = new StructBuffer <Span>(4);
     this.parentId = parentId;
 }
예제 #3
0
        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;
                }
            }
        }
예제 #4
0
        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);
                }
            }
        }