public ModelWrapper Create() { foreach (var connection in connections) { (bool success, ModelWrapper model) = connection.Get(); if (success) { return(model); } } semaphoreSlim.Wait(); try { if (connections.Count < options.MaxConnection) { var connection = new ConnectionWrapper(connectionFactory.CreateConnection(), options); (bool success, ModelWrapper model) = connection.Get(); connections.Add(connection); if (success) { return(model); } } throw new System.OverflowException(nameof(connections)); } finally { semaphoreSlim.Release(); } }
public ModelWrapper(ConnectionWrapper connectionWrapper, IModel model) { Connection = connectionWrapper; Model = model; persistentProperties = Model.CreateBasicProperties(); persistentProperties.Persistent = true; noPersistentProperties = Model.CreateBasicProperties(); noPersistentProperties.Persistent = false; }
public async ValueTask <ModelWrapper> PullModel() { ConnectionWrapper GetConnection() { var fullList = new List <ConnectionWrapper>(); while (connectionQueue.TryDequeue(out var connectionWrapper)) { if (connectionWrapper.Connection.IsOpen) { if (connectionWrapper.Increment() <= 16) { connectionQueue.Enqueue(connectionWrapper); return(connectionWrapper); } else { connectionWrapper.Decrement(); fullList.Add(connectionWrapper); } } } foreach (var item in fullList) { connectionQueue.Enqueue(item); } return(null); } if (!modelPool.TryDequeue(out var model)) { var conn = GetConnection(); if (conn == null && Interlocked.Increment(ref connectionCount) <= rabbitHost.MaxPoolSize) { Task.Run(() => { conn = new ConnectionWrapper { Client = this, Connection = _Factory.CreateConnection(rabbitHost.EndPoints) }; conn.Increment(); connectionQueue.Enqueue(conn); }).GetAwaiter().GetResult(); } else { Interlocked.Decrement(ref connectionCount); } if (conn != null) { model = new ModelWrapper(conn, conn.Connection.CreateModel()); model.Model.ConfirmSelect(); modelList.Add(model); } } if (model == null) { var taskSource = new TaskCompletionSource <ModelWrapper>(); modelTaskPool.Enqueue(taskSource); var cancelSource = new CancellationTokenSource(3000); cancelSource.Token.Register(() => { taskSource.SetException(new Exception("get rabbitmq's model timeout")); }); model = await taskSource.Task; } return(model); }