Is there a way to automatically force MongoDB C # Driver not to throw an EndOfStreamException if the main server is down?

I tested the official MongoDB C # driver with a set of replicas of 3 instances. I created a simple application that accesses a set of replicas in a loop.

My question is: is it possible to get the C # driver to restart the request automatically when I close the primary server without throwing an EndOfStreamException, as of now?

Here is my initialization code for MongoServerSettings:

var settings = new MongoServerSettings() { ConnectionMode = ConnectionMode.ReplicaSet, ReplicaSetName = "mongors", ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred), SafeMode = SafeMode.True, DefaultCredentials = new MongoCredentials("user", "password"), Servers = new[] { new MongoServerAddress("server.net", 27020), new MongoServerAddress("server.net", 27019), new MongoServerAddress("server.net", 27018)} }; 

And here is the code where I request the server:

  while (true) { var server = MongoServer.Create(settings); var db = server.GetDatabase("db"); var collection = db.GetCollection<TaggedAction>("actions"); var query = Query.EQ("_id", id); var entity = collection.FindOne(query); Console.WriteLine(DateTime.Now +" " + entity.ActionName); Thread.Sleep(2500); } 

If I disconnect the main server, the client throws the following exception:

 System.IO.EndOfStreamException was unhandled HResult=-2147024858 Message=Attempted to read past the end of the stream. Source=MongoDB.Bson StackTrace: at MongoDB.Bson.IO.BsonBuffer.LoadFrom(Stream stream, Int32 count) in C:\work\rstam\mongo-csharp-driver\Bson\IO\BsonBuffer.cs: line 314 at MongoDB.Bson.IO.BsonBuffer.LoadFrom(Stream stream) in C:\work\rstam\mongo-csharp-driver\Bson\IO\BsonBuffer.cs: line 281 at MongoDB.Driver.Internal.MongoConnection.ReceiveMessage(BsonBinaryReaderSettings readerSettings, IBsonSerializationOptions serializationOptions) in C:\work\rstam\mongo-csharp-driver\Driver\Internal\MongoConnection.cs: line 478 at MongoDB.Driver.MongoCursorEnumerator`1.GetReply(MongoConnection connection, MongoRequestMessage message) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 296 at MongoDB.Driver.MongoCursorEnumerator`1.GetFirst() in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 253 at MongoDB.Driver.MongoCursorEnumerator`1.MoveNext() in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 141 at System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) at MongoDB.Driver.MongoCollection.FindOneAs(IMongoQuery query) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCollection.cs: line 557 at MongoDB.Driver.MongoCollection`1.FindOne(IMongoQuery query) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCollection.cs: line 1734 at ConsoleApplication16.Program.Main(String[] args) in Program.cs: line 53 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: 

If I just swallow this exception and continue the cycle, everything will work. Thus, he can solve the problem and switch to another server. But it would be great if the driver could automatically deal with this, so that in no case would throw an exception. Is it possible?

+7
source share
1 answer

In many cases, it would be impossible to fail because the cursor that is running only exists on the primary server. Secondary people do not know anything about this and therefore cannot continue it.

In your case, you know that you know that you want to continue, but it is presumptuous of us to have your needs and apply them to all situations. If you just want to continue the cycle, others cannot.

In addition, some drivers make repeated requests. The .NET driver is not because we feel that we cannot always set the correct behavior and therefore leave it to the solution.

In the case of PrimaryPreferred, there is a reason why you want the readings to come from the Primary - because they are relevant. If we silently return to the secondary, then, depending on how far back the secondary, there is a chance that your query really returns results until the last successful query to the Primary. This is not a very good experience, and therefore we simply do not do this and we recommend that you catch these errors and handle the repetitions yourself.

We want to get some of these errors wrapped in MongoDB special cases, so you don't need to guess things like the EndOfStream exception (https://jira.mongodb.org/browse/CSHARP-474). Also, if you want to see this feature, write jira and we will look at how we can do it in a predictable way - perhaps using a strategy designed to handle retries (IRetryStrategy or something else).

+7
source

All Articles