elixir-mongo / mongodb

MongoDB driver for Elixir
Apache License 2.0
571 stars 156 forks source link

Mongo.Topology is raising an error #375

Closed wizardone closed 2 years ago

wizardone commented 2 years ago

I'm working on a project, which I inherited. Under the supervision tree mongo ecto is started:

children = [
      ....
      worker(MyApp.Repo, []),
      ....
    ]
Supervisor.start_link(children, opts)

The repo config looks like this:

config :my_app, MyApp.Repo,
  url: "mongo connection url",
  ssl: true,
  ssl_opts: [ciphers: [{:rsa, :aes_256_gcm, :aead, :sha384}], versions: [:"tlsv1.2"]],
  auth_source: "admin",
  pool_size: ENV.get("MONGODB_POOL_SIZE", 25)

AFAIK within the project all interactions with the Repo work just fine:

Repo.insert!(%SomeStruct{name: "App 1", id: "456"})

works just fine, however there are also several calls to the db, using Mongo directly, e.g.:

Mongo.find(MyApp.Repo, collection, %{_id: %{"$in" =>"some_ids"}})

These seem to result in an exception, irrespective of the type of operation performed:

[error] GenServer MobilePush.Repo terminating
** (FunctionClauseError) no function clause matching in :supervisor.handle_call/3
    (stdlib 3.12.1.1) supervisor.erl:400: :supervisor.handle_call(:topology, {#PID<0.660.0>, #Reference<0.3183091700.1983905797.4563>}, {:state, {:local,MyApp.Repo}, :one_for_one, {[Mongo], %{Mongo => {:child, #PID<0.698.0>, Mongo, {Ecto.Repo.Supervisor, :start_child, [{Mongo, :start_link, [[repo:MyApp.Repo, telemetry_prefix: [:my_app, :repo], otp_app: :my_app, timeout: 15000, pool_size: 10, auth_source: "admin", ssl: false, ssl_opts: [ciphers: [{:rsa, :aes_256_gcm, :aead, :sha384}], versions: [:"tlsv1.2"]], hostname: "", database: "", port: 27017, w: "majority", retryWrites: "true"]]}, MyApp.Repo, Mongo.Ecto, %{cache: #Reference<0.3183091700.1984036869.3533>, opts: [timeout: 15000, pool_size: 10], pool: {MyApp.Repo.Pool, [pool_timeout: 5000, repo: MyApp.Repo, telemetry_prefix: [:my_app, :repo], otp_app: :my_app, timeout: 15000, pool_size: 10, auth_source: "admin", ssl: false, ssl_opts: [ciphers: [{:rsa, :aes_256_gcm, :aead, :sha384}], versions: [:"tlsv1.2"]], hostname: "", database: "", port: 27017, w: "majority", retryWrites: "true"]}, repo: MyApp.Repo, telemetry: {MyApp.Repo, :debug, [:my_app, :repo, :query]}}]}, :permanent, 5000, :worker, [Ecto.Repo.Supervisor]}}}, :undefined, 0, 5, [], 0, Ecto.Repo.Supervisor, {MyApp.Repo, MyApp.Repo, :my_app, Mongo.Ecto, []}})

stacktrace:
       (elixir 1.10.4) lib/gen_server.ex:1023: GenServer.call/3
       (mongodb 1.0.0-beta.1) lib/mongo.ex:1242: Mongo.select_servers/4
       (mongodb 1.0.0-beta.1) lib/mongo.ex:1217: Mongo.select_server/3
       (mongodb 1.0.0-beta.1) lib/mongo.ex:700: Mongo.insert_one/4
       (mongodb 1.0.0-beta.1) lib/mongo.ex:729: Mongo.insert_one!/4

I've verified that mongo and mongo_ecto are working. Starting a manual Mongo process with

{:ok, conn} = Mongo.start_link(url: "mongodb://localhost:27017/db-name")

and then trying the same query (but passing in the newly created connection, not the repo)

Mongo.find(conn, collection, %{_id: %{"$in" =>"some_ids"}})

results in a normal response with no errors. Any ideas as to why this was happening? Also worth noting that this started happening after upgrading mongo and mongo_ecto to the latest beta releases.

scottmessinger commented 2 years ago

@wizardone I'm so sorry for the slow reply! I think this might be solved by changing MyApp.Repo to MyApp.Repo.pool()

I forget when that got changed, but we clearly need to update it in our docs. I'm going to close it for now b/c I'm pretty sure that's the problem, but please let me know if this isn't it. I'll try to reply sooner next time!

scottmessinger commented 2 years ago

@wizardone Just added a fix to the Readme which hopefully clarifies this:


Using with MongoDB Ecto

If you're using Mongo with the MongoDB Ecto library, where you have it defined in your config/runtime.exs like this:

config :my_app, MyApp.Repo,
  url: "mongo connection url"

You'll want to do reference mongo like this:

Mongo.find(MyApp.Repo.pool(), collection, %{_id: %{"$in" =>"some_ids"}})
wizardone commented 2 years ago

@scottmessinger Thank you for answering. I'm afraid I don't fully remember what the problem was, but I'm pretty sure that I had to specify the pool somewhere, so it was probably that. Good on updating the docs 👍