private bool FlushPayload(string path, PayloadQueue queue) { var payload = queue.DequeuePendingPayload(); if (payload == null) { return(false); } var metricsCount = payload.MetricsCount; var bytes = payload.Used; Debug.WriteLine($"BosunReporter: Flushing metrics batch. {metricsCount} metrics. {bytes} bytes."); var info = new AfterPostInfo(); var timer = new StopwatchStruct(); try { timer.Start(); PostToBosun(path, true, sw => sw.Write(payload.Data, 0, payload.Used)); timer.Stop(); queue.ReleasePayload(payload); PostSuccessCount++; TotalMetricsPosted += payload.MetricsCount; return(true); } catch (Exception ex) { timer.Stop(); // posting to Bosun failed, so put the batch back in the queue to try again later Debug.WriteLine("BosunReporter: Posting to the Bosun API failed. Pushing metrics back onto the queue."); PostFailCount++; info.Exception = ex; queue.AddPendingPayload(payload); throw; } finally { // don't use the payload variable in this block - it may have been released back to the pool by now info.Count = metricsCount; info.BytesWritten = bytes; info.MillisecondsDuration = timer.GetElapsedMilliseconds(); LastPostInfo = info; // Use BeginInvoke here to invoke the event listeners asynchronously. // We're inside a lock, so calling the listeners synchronously would put us at risk of a deadlock. AfterPost?.BeginInvoke(info, s_asyncNoopCallback, null); } }
private void FlushBatch() { var batch = DequeueMetricsBatch(); if (batch.Count == 0) { return; } Debug.WriteLine("BosunReporter: Flushing metrics batch. Size: " + batch.Count); var info = new AfterPostInfo(); var timer = new StopwatchStruct(); try { timer.Start(); PostToBosun("/api/put", true, sw => WriteJsonArrayBody(sw, batch)); timer.Stop(); PostSuccessCount++; TotalMetricsPosted += batch.Count; } catch (Exception ex) { timer.Stop(); // posting to Bosun failed, so put the batch back in the queue to try again later Debug.WriteLine("BosunReporter: Posting to the Bosun API failed. Pushing metrics back onto the queue."); PostFailCount++; info.Exception = ex; EnqueueMetrics(batch); throw; } finally { info.Count = batch.Count; info.MillisecondsDuration = timer.GetElapsedMilliseconds(); LastPostInfo = info; // Use BeginInvoke here to invoke the event listeners asynchronously. // We're inside a lock, so calling the listeners synchronously would put us at risk of a deadlock. AfterPost?.BeginInvoke(info, s_asyncNoopCallback, null); } }