2
2
using System . Collections . Concurrent ;
3
3
using System . Threading ;
4
4
using System . Threading . Tasks ;
5
+ using System . Threading . Tasks . Dataflow ;
5
6
using Jaeger . Exceptions ;
6
7
using Jaeger . Metrics ;
7
8
using Jaeger . Senders ;
@@ -18,7 +19,7 @@ public class RemoteReporter : IReporter
18
19
public const int DefaultMaxQueueSize = 100 ;
19
20
public static readonly TimeSpan DefaultFlushInterval = TimeSpan . FromSeconds ( 1 ) ;
20
21
21
- private readonly BlockingCollection < ICommand > _commandQueue ;
22
+ private readonly BufferBlock < ICommand > _commandQueue ;
22
23
private readonly Task _queueProcessorTask ;
23
24
private readonly TimeSpan _flushInterval ;
24
25
private readonly Task _flushTask ;
@@ -32,28 +33,22 @@ internal RemoteReporter(ISender sender, TimeSpan flushInterval, int maxQueueSize
32
33
_sender = sender ;
33
34
_metrics = metrics ;
34
35
_logger = loggerFactory . CreateLogger < RemoteReporter > ( ) ;
35
- _commandQueue = new BlockingCollection < ICommand > ( maxQueueSize ) ;
36
+ _commandQueue = new BufferBlock < ICommand > ( new DataflowBlockOptions ( ) {
37
+ BoundedCapacity = maxQueueSize
38
+ } ) ;
36
39
37
40
// start a thread to append spans
38
- _queueProcessorTask = Task . Factory . StartNew ( ProcessQueueLoop , TaskCreationOptions . LongRunning ) ;
41
+ _queueProcessorTask = Task . Run ( async ( ) => { await ProcessQueueLoop ( ) ; } ) ;
39
42
40
43
_flushInterval = flushInterval ;
41
44
_flushTask = Task . Run ( FlushLoop ) ;
42
45
}
43
46
44
47
public void Report ( Span span )
45
48
{
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
+
57
52
if ( ! added )
58
53
{
59
54
_metrics . ReporterDropped . Inc ( 1 ) ;
@@ -62,9 +57,7 @@ public void Report(Span span)
62
57
63
58
public async Task CloseAsync ( CancellationToken cancellationToken )
64
59
{
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 ( ) ;
68
61
69
62
try
70
63
{
@@ -100,16 +93,9 @@ internal void Flush()
100
93
// to reduce the number of updateGauge stats, we only emit queue length on flush
101
94
_metrics . ReporterQueueLength . Update ( _commandQueue . Count ) ;
102
95
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 ) ) ;
113
99
}
114
100
115
101
private async Task FlushLoop ( )
@@ -120,17 +106,18 @@ private async Task FlushLoop()
120
106
await Task . Delay ( _flushInterval ) . ConfigureAwait ( false ) ;
121
107
Flush ( ) ;
122
108
}
123
- while ( ! _commandQueue . IsAddingCompleted ) ;
109
+ while ( ! _commandQueue . Completion . IsCompleted ) ;
124
110
}
125
111
126
- private void ProcessQueueLoop ( )
112
+ private async Task ProcessQueueLoop ( )
127
113
{
128
114
// This blocks until a command is available or IsCompleted=true
129
- foreach ( ICommand command in _commandQueue . GetConsumingEnumerable ( ) )
115
+ while ( await _commandQueue . OutputAvailableAsync ( ) )
130
116
{
131
117
try
132
118
{
133
- command . ExecuteAsync ( ) . Wait ( ) ;
119
+ var command = await _commandQueue . ReceiveAsync ( ) ;
120
+ await command . ExecuteAsync ( ) ;
134
121
}
135
122
catch ( SenderException ex )
136
123
{
0 commit comments