@@ -18,10 +18,13 @@ internal sealed class AsynchronousMessageBus : BaseMessageBus, IMessageBus, IDis
1818 private readonly IEnvironment _environment ;
1919 private readonly ILogger < AsynchronousMessageBus > _logger ;
2020 private readonly bool _isTraceLoggingEnabled ;
21- private readonly Dictionary < IDataConsumer , AsyncConsumerDataProcessor > _consumerProcessor = [ ] ;
22- private readonly Dictionary < Type , List < AsyncConsumerDataProcessor > > _dataTypeConsumers = [ ] ;
21+ private readonly Dictionary < IDataConsumer , IAsyncConsumerDataProcessor > _consumerProcessor = [ ] ;
22+ private readonly Dictionary < Type , List < IAsyncConsumerDataProcessor > > _dataTypeConsumers = [ ] ;
2323 private readonly IDataConsumer [ ] _dataConsumers ;
2424 private readonly ITestApplicationCancellationTokenSource _testApplicationCancellationTokenSource ;
25+ #if ! NETCOREAPP
26+ private readonly bool _forceBlockingCollection ;
27+ #endif
2528 private bool _disabled ;
2629
2730 public AsynchronousMessageBus (
@@ -37,6 +40,12 @@ public AsynchronousMessageBus(
3740 _environment = environment ;
3841 _logger = loggerFactory . CreateLogger < AsynchronousMessageBus > ( ) ;
3942 _isTraceLoggingEnabled = _logger . IsEnabled ( LogLevel . Trace ) ;
43+ #if ! NETCOREAPP
44+ // Note: This env variable is only present temporarily.
45+ // Please, don't use it except for working around an issue that was reported to microsoft/testfx repo **and** a team member instructs you to do so.
46+ // This env variable is undocumented and we will remove it in a soon release.
47+ _forceBlockingCollection = _environment . GetEnvironmentVariable ( "MicrosoftTestingPlatform.MessageBus.UseBlockingCollection" ) == "1" ;
48+ #endif
4049 }
4150
4251 public override IDataConsumer [ ] DataConsumerServices
@@ -53,7 +62,7 @@ public override async Task InitAsync()
5362
5463 foreach ( Type dataType in consumer . DataTypesConsumed )
5564 {
56- if ( ! _dataTypeConsumers . TryGetValue ( dataType , out List < AsyncConsumerDataProcessor > ? asyncMultiProducerMultiConsumerDataProcessors ) )
65+ if ( ! _dataTypeConsumers . TryGetValue ( dataType , out List < IAsyncConsumerDataProcessor > ? asyncMultiProducerMultiConsumerDataProcessors ) )
5766 {
5867 asyncMultiProducerMultiConsumerDataProcessors = [ ] ;
5968 _dataTypeConsumers . Add ( dataType , asyncMultiProducerMultiConsumerDataProcessors ) ;
@@ -64,9 +73,15 @@ public override async Task InitAsync()
6473 throw new InvalidOperationException ( $ "Consumer registered two time for data type '{ dataType } ', consumer '{ consumer } '") ;
6574 }
6675
67- if ( ! _consumerProcessor . TryGetValue ( consumer , out AsyncConsumerDataProcessor ? asyncMultiProducerMultiConsumerDataProcessor ) )
76+ if ( ! _consumerProcessor . TryGetValue ( consumer , out IAsyncConsumerDataProcessor ? asyncMultiProducerMultiConsumerDataProcessor ) )
6877 {
78+ #if ! NETCOREAPP
79+ asyncMultiProducerMultiConsumerDataProcessor = _forceBlockingCollection
80+ ? new BlockingCollectionConsumerDataProcessor ( consumer , _task , _testApplicationCancellationTokenSource . CancellationToken )
81+ : new AsyncConsumerDataProcessor ( consumer , _task , _testApplicationCancellationTokenSource . CancellationToken ) ;
82+ #else
6983 asyncMultiProducerMultiConsumerDataProcessor = new AsyncConsumerDataProcessor ( consumer , _task , _testApplicationCancellationTokenSource . CancellationToken ) ;
84+ #endif
7085 _consumerProcessor . Add ( consumer , asyncMultiProducerMultiConsumerDataProcessor ) ;
7186 }
7287
@@ -103,7 +118,7 @@ public override async Task PublishAsync(IDataProducer dataProducer, IData data)
103118 throw new InvalidOperationException ( $ "Unexpected data type '{ dataType } ' produced by '{ dataProducer . Uid } '") ;
104119 }
105120
106- if ( ! _dataTypeConsumers . TryGetValue ( dataType , out List < AsyncConsumerDataProcessor > ? values ) )
121+ if ( ! _dataTypeConsumers . TryGetValue ( dataType , out List < IAsyncConsumerDataProcessor > ? values ) )
107122 {
108123 return ;
109124 }
@@ -127,7 +142,7 @@ private async Task LogDataAsync(IDataProducer dataProducer, IData data)
127142
128143 public override async Task DrainDataAsync ( )
129144 {
130- Dictionary < AsyncConsumerDataProcessor , long > consumerToDrain = [ ] ;
145+ Dictionary < IAsyncConsumerDataProcessor , long > consumerToDrain = [ ] ;
131146 bool anotherRound = true ;
132147 string ? customAttempts = _environment . GetEnvironmentVariable ( EnvironmentVariableConstants . TESTINGPLATFORM_MESSAGEBUS_DRAINDATA_ATTEMPTS ) ;
133148 if ( ! int . TryParse ( customAttempts , out int totalNumberOfDrainAttempt ) )
@@ -149,7 +164,7 @@ public override async Task DrainDataAsync()
149164 StringBuilder builder = new ( ) ;
150165 builder . Append ( CultureInfo . InvariantCulture , $ "Publisher/Consumer loop detected during the drain after { stopwatch . Elapsed } .\n { builder } ") ;
151166
152- foreach ( ( AsyncConsumerDataProcessor key , long value ) in consumerToDrain )
167+ foreach ( ( IAsyncConsumerDataProcessor key , long value ) in consumerToDrain )
153168 {
154169 builder . AppendLine ( CultureInfo . InvariantCulture , $ "Consumer '{ key . DataConsumer } ' payload received { value } .") ;
155170 }
@@ -159,9 +174,9 @@ public override async Task DrainDataAsync()
159174
160175 totalNumberOfDrainAttempt -- ;
161176 anotherRound = false ;
162- foreach ( List < AsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
177+ foreach ( List < IAsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
163178 {
164- foreach ( AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
179+ foreach ( IAsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
165180 {
166181 consumerToDrain . TryAdd ( asyncMultiProducerMultiConsumerDataProcessor , 0 ) ;
167182
@@ -185,9 +200,9 @@ public override async Task DisableAsync()
185200
186201 _disabled = true ;
187202
188- foreach ( List < AsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
203+ foreach ( List < IAsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
189204 {
190- foreach ( AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
205+ foreach ( IAsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
191206 {
192207 await asyncMultiProducerMultiConsumerDataProcessor . CompleteAddingAsync ( ) . ConfigureAwait ( false ) ;
193208 }
@@ -196,9 +211,9 @@ public override async Task DisableAsync()
196211
197212 public override void Dispose ( )
198213 {
199- foreach ( List < AsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
214+ foreach ( List < IAsyncConsumerDataProcessor > dataProcessors in _dataTypeConsumers . Values )
200215 {
201- foreach ( AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
216+ foreach ( IAsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors )
202217 {
203218 asyncMultiProducerMultiConsumerDataProcessor . Dispose ( ) ;
204219 }
0 commit comments