Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Passing :read_preference globally #206

Closed
JohannesSoots opened this issue Sep 11, 2023 · 9 comments
Closed

Passing :read_preference globally #206

JohannesSoots opened this issue Sep 11, 2023 · 9 comments
Assignees

Comments

@JohannesSoots
Copy link

Hi! I'm trying to set read_preference globally, right now as far as I see you have to pass them to each query explicitly.

Looking through code, would it make sense if :read_preference was passed to Mongo.start_link/1 then right now it would already be stored in Mongo.Topology state in which case it could be used when :checkout_session happens?

Or allow passing this via URL params would also be an option.

@zookzook
Copy link
Owner

Sounds good. It seems that this is missing! The read-preferences are already in the topology process. I will take a look at the code.

@zookzook zookzook self-assigned this Sep 11, 2023
@JohannesSoots
Copy link
Author

Sounds good. It seems that this is missing! The read-preferences are already in the topology process. I will take a look at the code.

Awesome, thanks! We initially had the readPreference in the URL params and I noticed it was parsed and passed to Topology, but it's not parsed into the same format as the driver expects. Not sure if it will cause conflict as is, so might make sense either to exclude parsing these entirely or map them into expected format.

For example &readPreference=nearest&readPreferenceTags=dc:west would get parsed [read_preference: :nearest, read_preference_tags: "dc:west"]. These would be passed down with other options.

@zookzook
Copy link
Owner

You can try the PR #207 to see if this is working.

@JohannesSoots
Copy link
Author

JohannesSoots commented Sep 12, 2023

If passing them from query params it seems to work parse and passes the read preference properly, but when given :read_preference to Mongo.start_link/1 then it blows up.

read_preference: %{
    mode: :secondary,
    max_staleness_ms: 120_000,
    tag_sets: [dc: "west", usage: "production"]
}
** (Mix) Could not start application my_app: Application.start(:normal, []) returned an error: shutdown: failed to start child: :mongo
    ** (EXIT) an exception was raised:
        ** (FunctionClauseError) no function clause matching in String.split/3
            (elixir 1.14.0) lib/string.ex:479: String.split([], ",", [])
            (mongodb_driver 1.2.0) lib/mongo/url_parser.ex:238: Mongo.UrlParser.parse_tags/1
            (mongodb_driver 1.2.0) lib/mongo/url_parser.ex:217: Mongo.UrlParser.extend_read_preference_tags/2
            (mongodb_driver 1.2.0) lib/mongo/url_parser.ex:207: Mongo.UrlParser.process_read_preferences/1
            (mongodb_driver 1.2.0) lib/mongo/url_parser.ex:186: Mongo.UrlParser.parse_url/1
            (mongodb_driver 1.2.0) lib/mongo.ex:140: Mongo.start_link/1
            (stdlib 4.2) supervisor.erl:414: :supervisor.do_start_child_i/3
            (stdlib 4.2) supervisor.erl:400: :supervisor.do_start_child/2
            (stdlib 4.2) supervisor.erl:384: anonymous fn/3 in :supervisor.start_children/2
            (stdlib 4.2) supervisor.erl:1250: :supervisor.children_map/4
            (stdlib 4.2) supervisor.erl:350: :supervisor.init_children/2
            (stdlib 4.2) gen_server.erl:851: :gen_server.init_it/2
            (stdlib 4.2) gen_server.erl:814: :gen_server.init_it/6
            (stdlib 4.2) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

@zookzook
Copy link
Owner

Let me fix this issue.

@zookzook
Copy link
Owner

I pushed a new PR that fixes the issue.

@JohannesSoots
Copy link
Author

Thanks a lot! Tested and so far passing read_preference works both ways either passing URL or as Keyword.

I don't know if this is intended or not, but when you set these read preferences, but you try to connect to single mongo instance not a cluster it timeouts in Topology :checkout_session. It's not issue for us really as we'll just configure it based on environment.

** (exit) exited in: GenServer.call(:mongo, {:checkout_session, :read, [batch_size: 1]}, 60000)
    ** (EXIT) time out
    (elixir 1.14.0) lib/gen_server.ex:1038: GenServer.call/3
    (mongodb_driver 1.2.0) lib/mongo/session.ex:146: Mongo.Session.start_session/3
    (mongodb_driver 1.2.0) lib/mongo/stream.ex:40: Mongo.Stream.checkout_session/2
    (mongodb_driver 1.2.0) lib/mongo/stream.ex:21: Mongo.Stream.new/3
    (mongodb_driver 1.2.0) lib/mongo.ex:776: Mongo.find/4
    (mongodb_driver 1.2.0) lib/mongo.ex:804: Mongo.find_one/4
    iex:218: (file)

@zookzook
Copy link
Owner

Yeah, this is correct, because of the tag_sets used there. With a singleton, it does not make sense. The topology process is not able to select a server and therefore the GenServer call will timeout.

@zookzook
Copy link
Owner

It is fixed so far, closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants