I am trying to Implement a pipeline to limit and execute all incoming request from API to mongoDB using this reference. I Have Implemented as Follows,
Singleton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Orniz.OE.BusinessObjects;
using MongoDB.Driver;
using System.Diagnostics;
using System.Configuration;
namespace DataAccess.Implementations
{
public class Singleton
{
private Singleton() { }
private static Singleton _instance;
private static string DBName = DBConnection.Database;
private static string connectionString = DBConnection.ConnectionString;
public static string PoolSize { get { return ConfigurationManager.AppSettings["OnlinePoolSize"].ToString(); } }
public IMongoDatabase db = null;
private static readonly object _lock = new object();
public static Singleton GetInstance()
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
try
{
_instance = new OnlineExamSingleton();
var mongo_url = MongoUrl.Create(connectionString);
MongoClientSettings settings = MongoClientSettings.FromUrl(mongo_url);
settings.MaxConnectionPoolSize = Convert.ToInt32(PoolSize);
_instance.client = new MongoClient(settings);
_instance.db = _instance.client.GetDatabase(DBName);
}
catch (Exception ex)
{
}
}
}
}
return _instance;
}
public static int MaxConnectionPoolSize
{
get
{
int defaultValue = 200;
string configValue = PoolSize;
if (string.IsNullOrEmpty(configValue))
{
return defaultValue;
}
else
{
int returnValue;
try
{
int configExpiryValue = Convert.ToInt32(configValue);
returnValue = configExpiryValue;
}
catch (Exception ex)
{
returnValue = defaultValue;
}
return returnValue;
}
}
}
public MongoClient client { get; set; }
public IMongoCollection<TDocument> Collection<TDocument>(string collection)
where TDocument : class
{
return db.GetCollection<TDocument>(collection);
}
}
}
**ConnectionThrottlingPipeline.cs * *
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DataAccess.Implementations
{
public class ConnectionThrottlingPipeline<T> : IConnectionThrottlingPipeline<T>
{
private readonly Semaphore openConnectionSemaphore;
public ConnectionThrottlingPipeline(IMongoClient client)
{
//Only grabbing half the available connections to hedge against collisions.
//If you send every operation through here
//you should be able to use the entire connection pool.
openConnectionSemaphore = new Semaphore(client.Settings.MaxConnectionPoolSize / 2,
client.Settings.MaxConnectionPoolSize / 2);
}
public async Task AddRequest(Func<Task> task)
{
try
{
openConnectionSemaphore.WaitOne();
try
{
await task();
}
finally
{
openConnectionSemaphore.Release();
}
}
catch (Exception ex)
{
}
}
}
}
**IConnectionThrottlingPipeline.cs * *
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.Implementations
{
public class IConnectionThrottlingPipeline<T>
{
}
}
**methodclass.cs * *
public static Singleton db = Singleton.GetInstance();
public async Task<bool> InsertData(Data data)
{
try
{
ConnectionThrottlingPipeline<Task> connectionThrottlingPipeline = new ConnectionThrottlingPipeline<Task>(Singleton.GetInstance().client);
var mycollection = db.Collection<Data>("mycollection");
await connectionThrottlingPipeline.AddRequest(() => mycollection.InsertOneAsync(data));
}
catch (Exception exception)
{
}
}
It 's giving me the below error upon testing with 4000 concurrent document write requests with 300 as default PoolSize, The exception occurs on Add request method. I wonder should I need to Implemet the class as Singleton too or is there something wrong in my Implementation ? can someone give me some insight on this ?
The wait queue for acquiring a connection to server myserver-shardtag14.mongodb.net:27017 is full.
at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.AcquireConnectionHelper.EnterWaitQueue() at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.d__38.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.Core.Servers.Server.d__34.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.Core.Operations.RetryableWriteContext.d__21.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.Core.Operations.RetryableWriteContext.d__1.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.d__44.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.OperationExecutor.d__51.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.MongoCollectionImpl
1.d__1001.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.MongoCollectionImpl
1.d__30.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.MongoCollectionImpl1.<UsingImplicitSessionAsync>d__106
1.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MongoDB.Driver.MongoCollectionBase`1.d__74.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()