Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Set read_preference to primaryPreferred when topology single with replica set. #266

Merged

Conversation

ColaCheng
Copy link
Contributor

@ColaCheng ColaCheng commented Feb 6, 2025

We found the issue with querying the data when we use directConnection=true and the cluster is a replica set. We got this error by using the following steps.

iex> {:ok, top} = Mongo.start_link(url: "mongodb://localhost:27018/test?directConnection=true&readPreference=secondary&authSource=admin&maxPoolSize=1")
{:ok, #PID<0.230.0>}
iex> Mongo.aggregate(top, "test", [], [])
{:error,
 %Mongo.Error{
   message: "not primary and secondaryOk=false",
   code: 13435,
   host: nil,
   fail_command: false,
   error_labels: [],
   resumable: true,
   retryable_reads: true,
   retryable_writes: true,
   not_writable_primary_or_recovering: true,
   error_info: nil
 }}

Then I traced the Python MongoDB driver source code and found it set read_preference to primaryPreferred when topology single with replica set. Here is the reference.

After the changes, the query will work.

iex> {:ok, top} = Mongo.start_link(url: "mongodb://localhost:27018/test?directConnection=true&readPreference=secondary&authSource=admin&maxPoolSize=1")
{:ok, #PID<0.213.0>}
iex> Mongo.aggregate(top, "test", [], [])
%Mongo.Stream{
  topology_pid: #PID<0.213.0>,
  session: {:own, #PID<0.229.0>},
  cursor: 0,
  coll: "test.test",
  docs: [],
  cmd: [aggregate: "test", pipeline: [], cursor: %{}],
  opts: [session: #PID<0.229.0>, compression: true]
}

Please review it. Thank you!

Copy link
Owner

@zookzook zookzook left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Please call mix credo. Thank you!


:sharded ->
{mongos_servers(topology), ReadPreference.to_mongos(read_preference)}
{mongos_servers(topology) |> pick_server(), ReadPreference.to_mongos(read_preference)}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you execute mix credo? It should complain about the |> operator.

topology  |> mongos_servers() |> pick_server()

Looks nicer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated it. Thanks!


_other ->
{select_replica_set_server(topology, read_preference.mode, read_preference), ReadPreference.to_replica_set(read_preference)}
{select_replica_set_server(topology, read_preference.mode, read_preference) |> pick_server(), ReadPreference.to_replica_set(read_preference)}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topology  |> select_replica_set_server(read_preference.mode, read_preference) |> pick_server()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated it. Thanks!

@zookzook zookzook merged commit db726e9 into zookzook:master Feb 6, 2025
5 checks passed
suchasurge pushed a commit to suchasurge/elixir-mongodb-driver that referenced this pull request Feb 25, 2025
…lica set. (zookzook#266)

* Set read preference as primaryPreferred when topology is single and is replica.

* Put missing replica? in ServerDescription.parse_hello_response/1 and add test.

* update code format.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants