using System.Diagnostics;
using BSI.Stack.Rabbit;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Rabbit;
///
/// 支持发布确认模式
///
public class RabbitClientBusExt : RabbitClientBus, ISingletonDependency
{
public RabbitClientBusExt(IServiceProvider sp, ILogger logger)
: base(sp, logger, sp.GetRequiredService>().CurrentValue)
{
}
public void PublishByConfirmSelect(
string exchange,
string routingKey,
byte[] data,
Action? options = null
)
{
using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
activity?.SetTag("kind", "publish");
var key = exchange + ":" + routingKey;
Lazy orAdd = Channels.GetOrAdd(key, (Func>) (_ => new Lazy(CreateModel)));
var basicProperties1 = orAdd.Value.CreateBasicProperties();
// 配置属性
if (options != null)
options(basicProperties1);
var model = orAdd.Value;
// 启用发布确认
model.ConfirmSelect();
var readOnlyMemory = (ReadOnlyMemory) data;
model.BasicPublish(exchange, routingKey, basicProperties1, readOnlyMemory);
model.WaitForConfirmsOrDie();
}
public void PublishByConfirmSelect(
string exchange,
string routingKey,
IEnumerable datas,
Action? options = null
)
{
using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
activity?.SetTag("kind", "publish");
var key = exchange + ":" + routingKey;
Lazy orAdd = Channels.GetOrAdd(key, (Func>) (_ => new Lazy(CreateModel)));
var basicProperties1 = orAdd.Value.CreateBasicProperties();
// 配置属性
if (options != null)
options(basicProperties1);
var model = orAdd.Value;
// 启用发布确认
model.ConfirmSelect();
foreach (var data in datas)
{
var readOnlyMemory = (ReadOnlyMemory) data;
model.BasicPublish(exchange, routingKey, basicProperties1, readOnlyMemory);
}
model.WaitForConfirmsOrDie();
}
private IConnection GetConnection()
{
var key = Connections.OrderBy((Func, int>) (q => q.Value)).Select((Func, IConnection>) (q => q.Key)).FirstOrDefault();
Connections.AddOrUpdate(key, (Func) (_ => 1), (Func) ((_, v) => v + 1));
return key;
}
private IModel CreateModel() => GetConnection().CreateModel();
}