Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

Commit e3b70cd

Browse files
BojanPantovic1989bojan.pantovic@redbox.comFalco20019
authored
Fix blocking code (#191)
* fixed blocking code in Reporters/RemoteReporter.cs Signed-off-by: Bojan Pantovic <[email protected]> * replace blocking collection with BufferBlock to make everything async Signed-off-by: Bojan Pantovic <[email protected]> * code review changes Signed-off-by: Bojan Pantovic <[email protected]> * code review changes #2 Signed-off-by: Bojan Pantovic <[email protected]> * Fix NuGET related build warnings Signed-off-by: Kraemer, Benjamin <[email protected]> Signed-off-by: Bojan Pantovic <[email protected]> Co-authored-by: [email protected] <[email protected]> Co-authored-by: Kraemer, Benjamin <[email protected]>
1 parent 462eef0 commit e3b70cd

File tree

2 files changed

+19
-31
lines changed

2 files changed

+19
-31
lines changed

src/Jaeger.Core/Jaeger.Core.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.0" />
1414
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
1515
<PackageReference Include="OpenTracing" Version="0.12.1" />
16+
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.11.1" />
1617
</ItemGroup>
1718

1819
</Project>

src/Jaeger.Core/Reporters/RemoteReporter.cs

+18-31
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Concurrent;
33
using System.Threading;
44
using System.Threading.Tasks;
5+
using System.Threading.Tasks.Dataflow;
56
using Jaeger.Exceptions;
67
using Jaeger.Metrics;
78
using Jaeger.Senders;
@@ -18,7 +19,7 @@ public class RemoteReporter : IReporter
1819
public const int DefaultMaxQueueSize = 100;
1920
public static readonly TimeSpan DefaultFlushInterval = TimeSpan.FromSeconds(1);
2021

21-
private readonly BlockingCollection<ICommand> _commandQueue;
22+
private readonly BufferBlock<ICommand> _commandQueue;
2223
private readonly Task _queueProcessorTask;
2324
private readonly TimeSpan _flushInterval;
2425
private readonly Task _flushTask;
@@ -32,28 +33,22 @@ internal RemoteReporter(ISender sender, TimeSpan flushInterval, int maxQueueSize
3233
_sender = sender;
3334
_metrics = metrics;
3435
_logger = loggerFactory.CreateLogger<RemoteReporter>();
35-
_commandQueue = new BlockingCollection<ICommand>(maxQueueSize);
36+
_commandQueue = new BufferBlock<ICommand>( new DataflowBlockOptions() {
37+
BoundedCapacity = maxQueueSize
38+
});
3639

3740
// start a thread to append spans
38-
_queueProcessorTask = Task.Factory.StartNew(ProcessQueueLoop, TaskCreationOptions.LongRunning);
41+
_queueProcessorTask = Task.Run(async () => { await ProcessQueueLoop(); });
3942

4043
_flushInterval = flushInterval;
4144
_flushTask = Task.Run(FlushLoop);
4245
}
4346

4447
public void Report(Span span)
4548
{
46-
bool added = false;
47-
try
48-
{
49-
// It's better to drop spans, than to block here
50-
added = _commandQueue.TryAdd(new AppendCommand(this, span));
51-
}
52-
catch (InvalidOperationException)
53-
{
54-
// The queue has been marked as IsAddingCompleted -> no-op.
55-
}
56-
49+
// It's better to drop spans, than to block here
50+
var added = _commandQueue.Post(new AppendCommand(this, span));
51+
5752
if (!added)
5853
{
5954
_metrics.ReporterDropped.Inc(1);
@@ -62,9 +57,7 @@ public void Report(Span span)
6257

6358
public async Task CloseAsync(CancellationToken cancellationToken)
6459
{
65-
// Note: Java creates a CloseCommand but we have CompleteAdding() in C# so we don't need the command.
66-
// (This also stops the FlushLoop)
67-
_commandQueue.CompleteAdding();
60+
_commandQueue.Complete();
6861

6962
try
7063
{
@@ -100,16 +93,9 @@ internal void Flush()
10093
// to reduce the number of updateGauge stats, we only emit queue length on flush
10194
_metrics.ReporterQueueLength.Update(_commandQueue.Count);
10295

103-
try
104-
{
105-
// We can safely drop FlushCommand when the queue is full - sender should take care of flushing
106-
// in such case
107-
_commandQueue.TryAdd(new FlushCommand(this));
108-
}
109-
catch (InvalidOperationException)
110-
{
111-
// The queue has been marked as IsAddingCompleted -> no-op.
112-
}
96+
// We can safely drop FlushCommand when the queue is full - sender should take care of flushing
97+
// in such case
98+
_commandQueue.Post(new FlushCommand(this));
11399
}
114100

115101
private async Task FlushLoop()
@@ -120,17 +106,18 @@ private async Task FlushLoop()
120106
await Task.Delay(_flushInterval).ConfigureAwait(false);
121107
Flush();
122108
}
123-
while (!_commandQueue.IsAddingCompleted);
109+
while (!_commandQueue.Completion.IsCompleted);
124110
}
125111

126-
private void ProcessQueueLoop()
112+
private async Task ProcessQueueLoop()
127113
{
128114
// This blocks until a command is available or IsCompleted=true
129-
foreach (ICommand command in _commandQueue.GetConsumingEnumerable())
115+
while (await _commandQueue.OutputAvailableAsync())
130116
{
131117
try
132118
{
133-
command.ExecuteAsync().Wait();
119+
var command = await _commandQueue.ReceiveAsync();
120+
await command.ExecuteAsync();
134121
}
135122
catch (SenderException ex)
136123
{

0 commit comments

Comments
 (0)