-
Type: Bug
-
Resolution: Duplicate
-
Priority: Unknown
-
None
-
Affects Version/s: 2.21.0, 2.28.0
-
Component/s: Connectivity
-
None
-
Dotnet Drivers
Summary
The C# driver fails to connect to the MongoDB Atlas M10 cluster some times. This happens around 40-50% of the times, and a retry usually succeeds. It also gets stuck on the connecting part for a long time (around 30 seconds) after which it times out.
This bug is not found in for example the Rust driver which always connects withing a couple hundred ms.
Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).
The C# driver versions that I have tested are 2.21 and 2.28. Our Atlas cluster is running 7.0.2. This was tested on Windows 11. We are using .Net 8.
How to Reproduce
- Create a Mongo Atlas cluster.
- Verify connection using Compass or some other software.
- Run the C# code.
- If it succeeds, run it again until it fails, usually for me it fails around 50% of the times.
Code for C#:
using MongoDB.Driver; using MongoDB.Bson; var connectionString = "mongodb+srv://some connection string to an atlas cluster"; Console.WriteLine("Started test"); for (int idx = 0; idx < 100; idx++){ var client = new MongoClient(connectionString); var collection = client.GetDatabase("database").GetCollection<MongoDataObj>("collection"); var filter = Builders<MongoDataObj>.Filter.Eq("Content", "foobar"); var document = collection.Find(filter).First(); Console.WriteLine($"Search nr: {idx}"); Console.WriteLine(document._id); Console.WriteLine(document.Content); Console.WriteLine("-----------------------------------");} public class MongoDataObj{ public ObjectId _id { get; set; } public string Content { get; set; } }
This will fail with one of these errors:
Unhandled exception. System.TimeoutException: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "ReplicaSet", Type : "ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/server-01:27017" }", EndPoint: "Unspecified/server-01:27017", ReasonChanged: "ServerInitialDescription", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", LastHeartbeatTimestamp: null, LastUpdateTimestamp: "2024-09-17T09:24:19.8985270Z" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/server-02:27017" }", EndPoint: "Unspecified/server-02:27017", ReasonChanged: "ServerInitialDescription", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", LastHeartbeatTimestamp: null, LastUpdateTimestamp: "2024-09-17T09:24:19.8995270Z" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/server-03:27017" }", EndPoint: "Unspecified/server-03:27017", ReasonChanged: "ServerInitialDescription", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", LastHeartbeatTimestamp: null, LastUpdateTimestamp: "2024-09-17T09:24:19.9006273Z" }] }. at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description) at MongoDB.Driver.Core.Clusters.Cluster.SelectServerHelper.WaitingForDescriptionToChange() at MongoDB.Driver.Core.Clusters.Cluster.SelectServer(IServerSelector selector, CancellationToken cancellationToken) at MongoDB.Driver.Core.Clusters.IClusterExtensions.SelectServerAndPinIfNeeded(ICluster cluster, ICoreSessionHandle session, IServerSelector selector, IReadOnlyCollection`1 deprioritizedServers, CancellationToken cancellationToken) at MongoDB.Driver.Core.Bindings.ReadPreferenceBinding.GetReadChannelSource(IReadOnlyCollection`1 deprioritizedServers, CancellationToken cancellationToken) at MongoDB.Driver.Core.Bindings.ReadPreferenceBinding.GetReadChannelSource(CancellationToken cancellationToken) at MongoDB.Driver.Core.Bindings.ReadBindingHandle.GetReadChannelSource(CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableReadContext.Initialize(CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableReadContext.Create(IReadBinding binding, Boolean retryRequested, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.FindOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken) at MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass52_0`1.<FindSync>b__0(IClientSessionHandle session) at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken) at MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken cancellationToken) at MongoDB.Driver.IAsyncCursorSourceExtensions.First[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken) at MongoDB.Driver.IFindFluentExtensions.First[TDocument,TProjection](IFindFluent`2 find, CancellationToken cancellationToken) at Program.<Main>$(String[] args) in C:\Users\codetest\test\Program.cs:line 13
Or
Unhandled exception. System.TimeoutException: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "ReplicaSet", Type : "ReplicaSet", State : "Disconnected", Servers : [] }.
The equivalent Rust code with driver version 3.1.0 doesn't have this issue:
use std::time::Duration; use mongodb::{ bson::{self, doc, oid::ObjectId}, options::{ClientOptions, ServerApi, ServerApiVersion}, Client, }; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] struct MongoDataObj { #[serde(rename = "_id")] id: ObjectId, pub Content: String, } #[tokio::main] async fn main() -> mongodb::error::Result<()> { let uri = "mongodb+srv://some connection string to an atlas cluster"; for n in 0..100 { let mut client_options = ClientOptions::parse(uri).await?; // Create a new client and connect to the server let client = Client::with_options(client_options)?; println!("Search nr: {}", n ); let collection = client .database("database") .collection::<MongoDataObj>("collection"); let filter = doc! { "Content": "foobar" }; let doc = collection.find_one(filter).await?; println!("{:?}", doc); println!("------------------------------------") } Ok(()) }
Extra info
The only way I have been able to make sure that the C# driver connects is either by having a try-catch that retries again until it succeeds, or increase all timeouts and idle times to 60 seconds. It will then connect at around 45-50 seconds.
The Rust code doesn't have this issue at all and is able to connect within 250-300ms.
The C# bug exists both in sync and async code.
- duplicates
-
CSHARP-5410 Occasional timeout errors with SRV connection strings
- Backlog
- is caused by
-
CSHARP-5410 Occasional timeout errors with SRV connection strings
- Backlog