[CSHARP-1102] Remove RequestStart from the public API Created: 13/Nov/14  Updated: 02/Apr/15  Resolved: 17/Nov/14

Status: Closed
Project: C# Driver
Component/s: Connectivity
Affects Version/s: None
Fix Version/s: 2.0

Type: Task Priority: Major - P3
Reporter: Robert Stam Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to JAVA-1544 Remove DB.requestStart, DB.requestDon... Closed
is related to PYTHON-785 Remove start_request() Closed
Backwards Compatibility: Major Change

 Description   

We are removing the ability to start and end requests in .NET.

The purpose of requests was to provide read-your-writes consistency when using w=0 write concern. Starting a request pins a socket to a thread so any operations on that thread end up in the same queue on the server side.

Justification for removing:

  • mongos 2.6+ doesn't support socket pinning by default, and mongos 2.8+ doesn't support it at all (SERVER-12273), so whatever weak consistency guarantees a request was supposed to provide are not provided with sharding.
  • It's a confusing feature that should rarely be used, if ever, yet people incorrectly use it all the time.
  • The connection pool cannot be utilized as efficiently.


 Comments   
Comment by Githook User [ 17/Nov/14 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1102: Remove RequestStart from the public API.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/2b3be94dd0da4d974b74151f535c1f382471b05a

Comment by Robert Stam [ 17/Nov/14 ]

We don't yet know what, if anything, will replace RequestStart in the new API.

Once that is determined we will link this ticket to any other related tickets.

Comment by Robert Stam [ 15/Nov/14 ]

As mentioned in the description above, the original motivation for RequestStart was to provide read-your-own-writes behavior when using a { w : 0 } WriteConcern.

But since then, RequestStart has been discovered to be useful in additional scenarios.

1. { w : 0 } throttling

Besides using RequestStart to ensure read-your-own-writes behavior when using { w : 0 }, it is also important to send all the unacknowledged writes over the same connection. Since you can stuff an arbitrary number of unacknowledged writes onto a connection, if you don't use a dedicated connection then the { w : 0 } writes can get randomly distributed over all the connections in your connection pool, essentially blocking all other operations that end up queued behind all the { w : 0 } writes.

This is mostly a historical issue, since { w : 0 } writes are going away.

2. Consistent reads from secondaries when connected to a replica set

When reading a number of related documents from secondaries, it is sometimes important that all the related documents be read from the same secondary. Otherwise, if the reads are randomly distributed over the secondaries, and if the secondaries happen to have different replication lags, you can get inconsistent results.

Unfortunately, as mentioned in the description above, using a single connection no longer ensures consistent reads from secondaries when reading through mongos.

3. Server version dependent code

If you have any code that does different things depending on the version of the server you are connected to, subtle issues can arise when connected to a deployment with mixed server versions. For example, if you check the version of one random secondary, but then allow the version dependent operations to be sent to another random secondary, the secondary that receives your operation might not be running the version you were expecting it to. The same issue can arise when connected to multiple mongos servers.

4. Fail points

This primarily affects our internal testing, but it is possible an application's test code might use fail points to test its own response to certain server failure modes. In our tests, if we set a fail point on a particular secondary, then we must ensure that the operations for that test are sent to the same secondary. If we allow the operations for that test to be sent to a random secondary, then the test will fail randomly.

5. GridFS

Our GridFS implementation uses RequestStart extensively to ensure that all operations related to a single high level GridFS operation go to the same server using the same connection. For uploads, this is only really important for { w : 0 } throttling. For downloads, it is an example of the need for consistent reads from secondaries. If we allow the chunks to be downloaded from random secondaries, which might have varying replication lags, the download could fail or be inconsistent.

However, even though RequestStart has proven useful in the above scenarios, it has two major flaws:

1. It is thread bound
2. Sometimes we only need to pin to a server, not a connection

The first issue is the biggest issue for us, as we move to an async based API, and execution of a Task bounces from thread to thread, so that a thread bound Request is useless.

The second issue is mostly a performance issue. Pinning to a connection certainly has the effect of pinning to a server, but it has the side effect of keeping that connection out of the connection pool for the duration of the request, which means it can't be used for anything else in the meantime.

Generated at Wed Feb 07 21:38:40 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.