[CDRIVER-3117] mongoc_database_command_with_opts does not default to DB read preference as documented Created: 07/May/19 Updated: 28/Oct/23 Resolved: 23/May/19 |
|
| Status: | Closed |
| Project: | C Driver |
| Component/s: | None |
| Affects Version/s: | 1.13.0, 1.14.0 |
| Fix Version/s: | 1.15.0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Kaitlin Mahar | Assignee: | Clyde Bazile III (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | docs | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
According to the documentation, if no read preference is passed in as a parameter and the command is not run in a transaction, mongoc_database_command_with_opts will use the database's read preference. However, this does not seem to be the case. I've managed to repro this in both 1.13.0 and 1.14.0 from Swift as follows, running against MongoDB 4.0.5 (omitted some cleanup code for brevity):
The APM callback prints out the following command, which shows primaryPreferred used as the read preference:
If I explicitly pass in the secondary read preference to mongoc_database_command_with_opts, the command uses secondary as well. Is this behavior intended? We use this method for our MongoDatabase.runCommand implementation. Currently we can work around this by just always passing in the DB's read preference if the user doesn't specify one via RunCommandOptions. |
| Comments |
| Comment by Githook User [ 23/May/19 ] |
|
Author: {'email': '34226620+bazile-clyde@users.noreply.github.com', 'name': 'bazile-clyde', 'username': 'bazile-clyde'}Message: |
| Comment by Githook User [ 23/May/19 ] |
|
Author: {'email': '34226620+bazile-clyde@users.noreply.github.com', 'name': 'bazile-clyde', 'username': 'bazile-clyde'}Message: |
| Comment by Kaitlin Mahar [ 07/May/19 ] |
|
patrick.freed pointed out to me that this is actually discussed in the SDAM spec:
Therefore, I believe libmongoc is doing the correct thing here, and it's just that the documentation is incorrect. |
| Comment by Kaitlin Mahar [ 07/May/19 ] |
|
Thanks jmikola. This method is only used for providing the runCommand method on MongoDatabase - we use the helpers everywhere else. The issues around selecting the wrong server seem problematic. FWIW, C++ driver also appears to use this method for its equivalent database.run_command method. |
| Comment by Jeremy Mikola [ 07/May/19 ] |
All of the command_with_opts methods utilize _mongoc_client_command_with_opts. At a quick glance, mongoc_database_command_with_opts appears to be consistent with mongoc_client_command_with_opts in that it specifies NULL as its default read preference. I do find it odd that the read, read_write, and write variants all pass the DB-level read prefs, so perhaps this is an oversight of the generic command_with_opts methods. I can tell you that using the generic command_with_opts method means that the is_read_command and is_write_command flags will never be set on the libmongoc command struct, which could lead to the wrong server being selected (e.g. selecting via read prefs instead of a writable server for a command that does write). Additionally, the generic method may prevent inheritance of client-level read or write concerns by the command document (may not be relevant if you're using higher-level helpers for things like findAndModify). |
| Comment by Kaitlin Mahar [ 07/May/19 ] |
|
As a follow on question to this, I noticed that there are several database methods for running commands, including a separate one for commands that both read and write, like mapReduce. Could it be problematic that we only ever use mongoc_database_command_with_opts regardless of the particular command a user passes in to our runCommand method? |