|
|
@@ -21,12 +21,11 @@ namespace DotNetCore.CAP.Processor |
|
|
|
private readonly CapOptions _options; |
|
|
|
private readonly ISubscribeDispatcher _executor; |
|
|
|
private readonly ILogger<Dispatcher> _logger; |
|
|
|
private readonly CancellationTokenSource _cts = new CancellationTokenSource(); |
|
|
|
|
|
|
|
private Channel<MediumMessage> _publishedChannel; |
|
|
|
private Channel<(MediumMessage, ConsumerExecutorDescriptor)> _receivedChannel; |
|
|
|
|
|
|
|
private readonly CancellationTokenSource _cts = new CancellationTokenSource(); |
|
|
|
|
|
|
|
public Dispatcher(ILogger<Dispatcher> logger, |
|
|
|
IMessageSender sender, |
|
|
|
IOptions<CapOptions> options, |
|
|
@@ -41,10 +40,26 @@ namespace DotNetCore.CAP.Processor |
|
|
|
public void Start(CancellationToken stoppingToken) |
|
|
|
{ |
|
|
|
stoppingToken.ThrowIfCancellationRequested(); |
|
|
|
stoppingToken.Register(() => _cts.Cancel()); |
|
|
|
stoppingToken.Register(() => _cts.Cancel()); |
|
|
|
|
|
|
|
var capacity = _options.ProducerThreadCount * 500; |
|
|
|
_publishedChannel = Channel.CreateBounded<MediumMessage>(new BoundedChannelOptions(capacity > 5000 ? 5000 : capacity) |
|
|
|
{ |
|
|
|
AllowSynchronousContinuations = true, |
|
|
|
SingleReader = _options.ProducerThreadCount == 1, |
|
|
|
SingleWriter = true, |
|
|
|
FullMode = BoundedChannelFullMode.Wait |
|
|
|
}); |
|
|
|
|
|
|
|
capacity = _options.ConsumerThreadCount * 300; |
|
|
|
_receivedChannel = Channel.CreateBounded<(MediumMessage, ConsumerExecutorDescriptor)>(new BoundedChannelOptions(capacity > 3000 ? 3000 : capacity) |
|
|
|
{ |
|
|
|
AllowSynchronousContinuations = true, |
|
|
|
SingleReader = _options.ConsumerThreadCount == 1, |
|
|
|
SingleWriter = true, |
|
|
|
FullMode = BoundedChannelFullMode.Wait |
|
|
|
}); |
|
|
|
|
|
|
|
_publishedChannel = Channel.CreateUnbounded<MediumMessage>(new UnboundedChannelOptions() { SingleReader = false, SingleWriter = true }); |
|
|
|
_receivedChannel = Channel.CreateUnbounded<(MediumMessage, ConsumerExecutorDescriptor)>(); |
|
|
|
|
|
|
|
Task.WhenAll(Enumerable.Range(0, _options.ProducerThreadCount) |
|
|
|
.Select(_ => Task.Factory.StartNew(() => Sending(stoppingToken), stoppingToken, TaskCreationOptions.LongRunning, TaskScheduler.Default)).ToArray()); |
|
|
@@ -55,12 +70,44 @@ namespace DotNetCore.CAP.Processor |
|
|
|
|
|
|
|
public void EnqueueToPublish(MediumMessage message) |
|
|
|
{ |
|
|
|
_publishedChannel.Writer.TryWrite(message); |
|
|
|
try |
|
|
|
{ |
|
|
|
if (!_publishedChannel.Writer.TryWrite(message)) |
|
|
|
{ |
|
|
|
while (_publishedChannel.Writer.WaitToWriteAsync(_cts.Token).AsTask().ConfigureAwait(false).GetAwaiter().GetResult()) |
|
|
|
{ |
|
|
|
if (_publishedChannel.Writer.TryWrite(message)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (OperationCanceledException) |
|
|
|
{ |
|
|
|
//Ignore |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void EnqueueToExecute(MediumMessage message, ConsumerExecutorDescriptor descriptor) |
|
|
|
{ |
|
|
|
_receivedChannel.Writer.TryWrite((message, descriptor)); |
|
|
|
try |
|
|
|
{ |
|
|
|
if (!_receivedChannel.Writer.TryWrite((message, descriptor))) |
|
|
|
{ |
|
|
|
while (_receivedChannel.Writer.WaitToWriteAsync(_cts.Token).AsTask().ConfigureAwait(false).GetAwaiter().GetResult()) |
|
|
|
{ |
|
|
|
if (_receivedChannel.Writer.TryWrite((message, descriptor))) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (OperationCanceledException) |
|
|
|
{ |
|
|
|
//Ignore |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private async Task Sending(CancellationToken cancellationToken) |
|
|
|