Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get connection status in the C# MongoDB driver v2.0?

We are starting using new MongoDB driver v2 and we can't understand whether we are connected to the db or not.

Our repository code:

var client = new MongoClient("mongodb://{wrong-host}:{wrong-port}/{dbbname}");
var database = client.GetDatabase(url.DatabaseName);

Where wrong-host and wrong-port are invalid values.

First we thought that exception will be raised if no one is listening on specified address but driver doesn't throws.

Next step was to invoke method on the db:

var dbs = client.ListDatabasesAsync().Result.ToListAsync().Result;

Here we have freez for 30 seconds and than exception. It was not suitable for us to wait 30 seconds to get to know connected we are or not.

System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode = Primary, TagSets = [] } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "****" }", EndPoint: "****", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it ******

Finally we tried to set up different timeouts but nothing changed.

var client = new MongoClient(new MongoClientSettings
  { 
    SocketTimeout = TimeSpan.FromSeconds(1),
    MaxConnectionIdleTime = TimeSpan.FromSeconds(1),
    MaxConnectionLifeTime = TimeSpan.FromSeconds(1),
    ConnectTimeout = TimeSpan.FromSeconds(1),
    Servers = url.Servers
  });

So the question is how we could know whether we are connected to the mongo or not in short time interval ~(1-2) seconds?

[UPD]

Our current solution is:

private IMongoDatabase Connect(string connectionString, TimeSpan timeout)
{
  var url = MongoUrl.Create(connectionString);
  var client = new MongoClient(url);
  var db = client.GetDatabase(url.DatabaseName);
  var pingTask = db.RunCommandAsync<BsonDocument>(new BsonDocument("ping", 1));
  pingTask.Wait(timeout);
  if (pingTask.IsCompleted)
    log.InfoFormat("Connected to: {0}.", connectionString);
  else
    throw new TimeoutException(string.Format("Failed to connect to: {0}.", connectionString));

  return db;
}

usage

database = Connect(connectionString, TimeSpan.FromSeconds(1));
like image 231
user854301 Avatar asked Jun 10 '15 14:06

user854301


1 Answers

There is next workaround for this issue:

var client = new MongoClient(new MongoClientSettings
{
       Server = new MongoServerAddress("xxxx"),
       ClusterConfigurator = builder =>
       {
             builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(10)));
       }
});
like image 196
rnofenko Avatar answered Sep 19 '22 13:09

rnofenko