fireproofsocks

fireproofsocks

Mongo connection times out, but only when it is used by a dependency

I’m experiencing some odd behavior. I’m using mongodb_driver (v0.9.0) in an app (app1), and it’s been working great. But suddenly, when I use that app as a dependency (by app2), suddenly all my mongo queries time out.

My guess is that I’m stepping into something tricky with supervisors or something. (Why am I doing this? My thought was that app1 defines all the schemas and contexts for how to access resources, and I didn’t want to duplicate any of that in app2 – I want app2 to be ignorant about the “implementation details”).

app1 wraps the Mongo start like this:

def MyMongoWrapper do
  def start_link(opts \\ []) do
    # Read some config here... user, password, etc.
    Mongo.start_link(opts)
  end
end

which is ref’d in app1’s application.ex:

def start(_type, _args) do
    children = [
      {MyMongoWrapper, []}
    ]
    opts = [strategy: :one_for_one, name: App1.Supervisor]
    Supervisor.start_link(children, opts)
  end

So all is well with the world in app1: I can start it up and make queries as expected.

But when I start working with app2 and I use app1 as a dependency, nothing seems to work, even though app1 DOES get started and the mongo process DOES get started.

Instead of relying on “implicit starting” (?) that happens when an app lists another app as a dependency, I tried manually listing App1 in app2’s supervision tree, but calls to Mongo still time out.

Likewise, if I remove all the children from app1’s application.ex and list the MyMongoWrapper in app2’s application.ex, I get the same result: any Mongo queries cause an exit due to timeout.

It’s really making me scratch my head and wonder why things are working in app1 at all. The config and everything seems to be exactly the same.

Does anyone have any ideas of what might be causing this type of behavior or other things I could check?

Marked As Solved

zookzook

zookzook

The driver 0.9.2 does not support 4.0. Sorry, you need to downgrade the driver. It does not support AWS DocumentDB.

Also Liked

zookzook

zookzook

I assume, your configuration is not working. Please turn on logging: GitHub - zookzook/elixir-mongodb-driver: MongoDB driver for Elixir, then you see more information about.

fireproofsocks

fireproofsocks

Thanks for the prompt reply @zookzook! This is interesting. I have verified that BOTH app1 and app2 have the IDENTICAL configuration options, something like this:

[
  name: :my_mongo,
  pool_size: 20,
  url: "mongodb://:@localhost:/app1_dev",
  timeout: 15000,
  ssl: false
]

Note that the URL looks funny in dev because we don’t specify a user, password, port, or parameters (which do get set when connecting to a production mongo instance).

What is really curious is that BOTH app1 AND app2 show errors on startup when I set the config to include log: true:

10:13:33.630 [error] an exception was raised logging %DBConnection.LogEntry{call: :execute, connection_time: 5298000, decode_time: 6000, idle_time: 548338000, params: [], pool_time: 147000, query: %Mongo.Query{action: {:exec_hello, []}}, result: {:ok, %Mongo.Query{action: {:exec_hello, []}}, {%{"code" => 59, "codeName" => "CommandNotFound", "errmsg" => "no such command: 'helloOk'", "ok" => 0.0}, %Mongo.Events.CommandStartedEvent{command: :hello, command_name: :hello, connection_id: #PID<0.815.0>, database_name: "admin", operation_id: nil, request_id: 1}, 0, 5240}}}: ** (BadFunctionError) expected a function, got: true
    (db_connection 2.4.2) lib/db_connection.ex:1532: DBConnection.log/2
    (db_connection 2.4.2) lib/db_connection.ex:1510: DBConnection.log/5
    (mongodb_driver 0.9.2) lib/mongo.ex:1526: Mongo.exec_hello/2
    (stdlib 3.16.1) timer.erl:166: :timer.tc/1
    (mongodb_driver 0.9.2) lib/mongo/monitor.ex:239: Mongo.Monitor.get_server_description/1
    (mongodb_driver 0.9.2) lib/mongo/monitor.ex:164: Mongo.Monitor.update_server_description/1
    (mongodb_driver 0.9.2) lib/mongo/monitor.ex:151: Mongo.Monitor.handle_info/2
    (stdlib 3.16.1) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.16.1) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.16.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

app1 throws 3 of these errors, and then they pop up intermittently, but app1 can go on to successfully issue commands, e.g.

# app1
iex> Mongo.insert_one(:my_mongo, "foo", %{what: "up"})
{:ok,
 %Mongo.InsertOneResult{
   acknowledged: true,
   inserted_id: #BSON.ObjectId<633d93aac6e47b35cb0d1fc5>
 }}

whereas app2 just throws an unending stream of these errors into the log. The same command on app2 yields a timeout:

# app2
iex> Mongo.insert_one(:my_mongo, "foo", %{what: "up"})
** (exit) exited in: GenServer.call(:my_mongo, {:checkout_session, :write, [write_counter: 1]}, 60000)
    ** (EXIT) time out
    (elixir 1.13.4) lib/gen_server.ex:1030: GenServer.call/3
    (mongodb_driver 0.9.2) lib/mongo/session.ex:142: Mongo.Session.start_session/3
    (mongodb_driver 0.9.2) lib/mongo/session.ex:694: Mongo.Session.in_session/5
    (mongodb_driver 0.9.2) lib/mongo.ex:1482: Mongo.issue_command/4
    (mongodb_driver 0.9.2) lib/mongo.ex:849: Mongo.insert_one/4

It’s like Mongo “knows” how its server is getting started or something. Very curious. Any other ideas for what could explain this behavior?

I just noticed app1 shows "mongodb_driver": {:hex, :mongodb_driver, "0.9.1" in its mix.lock whereas app2 specifies "mongodb_driver": {:hex, :mongodb_driver, "0.9.2" … so I’m gonna suss that out

zookzook

zookzook

If both apps have identical configurations then they started the supervisor related stuff twice. Use only one configuration. A topology should only started as a singleton.

fireproofsocks

fireproofsocks

Ok, we’ll pin it to v0.9.1. Thanks for the responses! They are much appreciated.
This really is a great driver – I’d love to see an Ecto adapter for it. We’ve got a handful of code that could maybe be adapted for that.

Interesting re DocumentDB: we are using DocumentDB in production with mongodb_driver v0.9.1 and it has been working fine – admittedly our queries are limited to mostly CRUD without a lot of filters or sorting, but it hasn’t had any issues.

zookzook

zookzook

I committed a fix on the master branch. Feel free to test it. If it is working like expected, then I will draft a new release for the fix!

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement