|
|
|
@ -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(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|