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

:jamdb_oracle_conn is reading messages not intended for the driver; breaking test flows #178

Open
adobley opened this issue Apr 2, 2024 · 4 comments

Comments

@adobley
Copy link

adobley commented Apr 2, 2024

We have been observing some failures in our tests related to the Jamdb.Oracle driver.

[error] Jamdb.Oracle (#PID<0.1313.0>) disconnected: ** (DBConnection.ConnectionError) :function_clause

We were able to narrow down the commit that introduced this behavior to 7edff83

When we add debug statements to the :jamdb_oracle_conn code we can see that it is erroring when trying to process a message that it read. This message in our case contains information added to the Process message queue by Plug.Conn for use in the test behaviors. Without the genserver in :jamdb_oracle the :jamdb_oracle_conn is reading any message off the current Process messages. While this seems to be handled OK in our running app, as far as we have seen, it does break testing.

We have a minimal reproduction in this script without the need for all our testing resources. This script just connects to a Oracle and tries to read off of the DUAL table. However, once there is some message on the Process messages it will fail for jambd_oracle versions 0.5.7 and newer.

#!/usr/bin/env elixir
Mix.install([
  {:ecto_sql, "~> 3.10"},
  {:jamdb_oracle, "0.5.7"}
])

username = System.get_env("ORACLE_USERNAME") || "system"
password = System.get_env("ORACLE_PASSWORD") || "oracle"
hostname = System.get_env("ORACLE_HOSTNAME") || "localhost"
port = System.get_env("ORACLE_PORT") || "1521"
database = System.get_env("ORACLE_DATABASE") || "XE"
url = "ecto://#{username}:#{password}@#{hostname}:#{port}/#{database}"

Application.put_env(:foo, Repo, url: url)

defmodule Repo do
  use Ecto.Repo,
    adapter: Ecto.Adapters.Jamdb.Oracle,
    otp_app: :foo
end

defmodule Main do
  import Ecto.Query, warn: false

  def main do
    Supervisor.start_link([Repo], strategy: :one_for_one)
    IO.inspect(Repo.query("SELECT * FROM DUAL"), label: "works")
    send(self(), :foo)
    IO.inspect(Repo.query("SELECT * FROM DUAL"), label: "errors with :function_clause")
  end
end

Main.main()

Is there a way we can prevent the :jamdb_oracle_conn from reading messages that are not intended for it? This behavior is disrupting our ability to test our app.

@vstavskyi
Copy link
Member

Can't fix it fast,
I'll publish 0.5.10 with pid in jamdb_oracle.ex like before 0.5.7

@adobley
Copy link
Author

adobley commented Apr 4, 2024

Thank you! I've got a patch that seems to fix the issue for this reproduction. But I'm fairly new to erlang, so it may not be the right way to address this issue. I'll open a draft PR in case it helps.

adobley added a commit to adobley/jamdb_oracle that referenced this issue Apr 4, 2024
we observed in erlangbureau#178 that unexpected messages could cause function_clause
errors by guarding on the expected types we gain some guarantees about
the message contents
adobley added a commit to adobley/jamdb_oracle that referenced this issue Apr 4, 2024
We observed in erlangbureau#178 that unexpected messages could cause function_clause
errors. By guarding on the expected types we gain some guarantees about
the message contents.
@vstavskyi
Copy link
Member

vstavskyi commented Apr 5, 2024

Try my commit with flush()

@adobley
Copy link
Author

adobley commented Apr 15, 2024

Sorry about the delay! This fell off my radar. This looks like it addresses our issue.

I was worried that flushing would cause information that the Plug was expecting to find would get lost. However in our current end to end tests this doesn't cause us any issues.

Thanks for addressing this so quickly! Really appreciate your help.

I'm happy to close this if this is something you're looking to promote to master.

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