|
|
|
|
@ -1,4 +1,7 @@
|
|
|
|
|
using RabbitMQ.Client;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using RabbitMQ.Client;
|
|
|
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
|
|
|
|
|
|
namespace Volo.Abp.RabbitMQ
|
|
|
|
|
@ -7,16 +10,43 @@ namespace Volo.Abp.RabbitMQ
|
|
|
|
|
{
|
|
|
|
|
protected IConnectionPool ConnectionPool { get; }
|
|
|
|
|
|
|
|
|
|
protected ConcurrentDictionary<string, ChannelPoolItem> Channels { get; }
|
|
|
|
|
|
|
|
|
|
public ChannelPool(IConnectionPool connectionPool)
|
|
|
|
|
{
|
|
|
|
|
ConnectionPool = connectionPool;
|
|
|
|
|
Channels = new ConcurrentDictionary<string, ChannelPoolItem>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual IChannelAccessor Acquire(string channelName = null)
|
|
|
|
|
{
|
|
|
|
|
//TODO: Pool channels!
|
|
|
|
|
channelName = channelName ?? "";
|
|
|
|
|
|
|
|
|
|
var poolItem = Channels.GetOrAdd(channelName, _ => new ChannelPoolItem
|
|
|
|
|
{
|
|
|
|
|
Channel = CreateChannel(channelName)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
lock (poolItem)
|
|
|
|
|
{
|
|
|
|
|
while (poolItem.IsInUse)
|
|
|
|
|
{
|
|
|
|
|
Monitor.Wait(poolItem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
poolItem.IsInUse = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new ChannelAccessor(
|
|
|
|
|
CreateChannel(channelName)
|
|
|
|
|
poolItem.Channel,
|
|
|
|
|
() =>
|
|
|
|
|
{
|
|
|
|
|
lock (poolItem)
|
|
|
|
|
{
|
|
|
|
|
poolItem.IsInUse = false;
|
|
|
|
|
Monitor.PulseAll(poolItem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -29,15 +59,17 @@ namespace Volo.Abp.RabbitMQ
|
|
|
|
|
protected class ChannelAccessor : IChannelAccessor
|
|
|
|
|
{
|
|
|
|
|
public IModel Channel { get; }
|
|
|
|
|
private readonly Action _disposeAction;
|
|
|
|
|
|
|
|
|
|
public ChannelAccessor(IModel channel)
|
|
|
|
|
public ChannelAccessor(IModel channel, Action disposeAction)
|
|
|
|
|
{
|
|
|
|
|
_disposeAction = disposeAction;
|
|
|
|
|
Channel = channel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Channel.Dispose();
|
|
|
|
|
_disposeAction.Invoke();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|