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

Proxy info messages to the adapter #316

Merged
merged 8 commits into from
Nov 12, 2024

Conversation

ruslandoga
Copy link
Contributor

Context: #315 (comment)

@ruslandoga ruslandoga changed the title proxy info messages to the adapter Proxy info messages to the adapter Nov 11, 2024
@@ -333,11 +333,11 @@ defmodule DBConnection.Connection do
def handle_event(:info, msg, :no_state, %{mod: mod, state: state} = s) do
if function_exported?(mod, :handle_info, 2) do
case apply(mod, :handle_info, [msg, state]) do
Copy link
Contributor Author

@ruslandoga ruslandoga Nov 11, 2024

Choose a reason for hiding this comment

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

I'm still passing the state to the callback since the monitor ref / socket ref would be there, and they are probably needed to match on the incoming message.

def handle_info({:DOWN, _ref, _type, sock, _info}, {sock, _buffer} = s) do
{:disconnect, TCPConnection.Error.exception({:idle, :closed}), s}
def handle_info({:DOWN, _ref, _type, sock, _info}, {sock, _buffer}) do
{:disconnect, TCPConnection.Error.exception({:idle, :closed})}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like here.


assert_receive {:connected, conn}
send(conn, "some harmless message")
assert P.run(pool, fn _ -> :result end) == :result
Copy link
Contributor Author

@ruslandoga ruslandoga Nov 11, 2024

Choose a reason for hiding this comment

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

I'm using this just to "sync" with the connection process, i.e. wait until it has processed all the messages. Maybe there is a better way? I know some people use :sys.get_state/1 (e.g. :sys.get_state(conn) in this case) but don't know if it's any better.

@ruslandoga ruslandoga marked this pull request as ready for review November 11, 2024 12:48
@ruslandoga ruslandoga requested a review from josevalim November 11, 2024 12:58
@josevalim josevalim merged commit 5d088f7 into elixir-ecto:master Nov 12, 2024
1 of 2 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

@ruslandoga
Copy link
Contributor Author

Seems like I forgot to run formatter on examples/ directory.

@josevalim
Copy link
Member

I just did it in main, no worries. But we also forgot to document handle_info as a callback and list it as optional. Can you please send a PR to add that too? Sorry.

@ruslandoga
Copy link
Contributor Author

Sure!

@ruslandoga
Copy link
Contributor Author

ruslandoga commented Nov 12, 2024

Hm... I tried handle_info/2 out in plausible/ch#212 and something seems off. DBConnection.execute gets an old connection even though it happens strictly after reconnect.

connect: #Port<0.10>
handshake (in connect): "select 1" on #Port<0.10>
-- first spawn --
handle_execute: "select 1 + 1" on #Port<0.10>
handle_info: #Port<0.10> closed :: {:disconnect, %Mint.TransportError{reason: :closed}}
disconnect: #Port<0.10>
connect: #Port<0.12>
handshake (in connect): "select 1" on #Port<0.12>
-- second spawn --
handle_execute: "select 1 + 1" on #Port<0.10> <-- old conn

I'll look into it more tomorrow, but first thought is ETS holds onto the old conn for some reason and checkout happens before pool_update(new_state) even though connection completes before the checkout. It might be time to finally learn how DBConnection does its magic :)


UPDATE: It seems like the ETS table is not updated on disconnect, so the very next query gets a stale conn.

@ruslandoga
Copy link
Contributor Author

ruslandoga commented Dec 5, 2024

👋 @josevalim

It doesn't seem like handle_info is of any use since the internal disconnect event doesn't remove "stale" connections from the ETS table. I think I will need to explore other solutions.

Should I revert this PR?

@josevalim
Copy link
Member

@ruslandoga it is up to you. Couldn't we allow :disconnect to be returned from handle_info and then have that remove it from the table? Another option is to do a checkout, like we do on ping, and then it will be properly disconnected. But in such case we need to be very clear that handle_info in our case is a relatively expensive operation, as it checks out, and it must be used only in cases like this.

@ruslandoga
Copy link
Contributor Author

ruslandoga commented Dec 19, 2024

ReqCH gave me an idea that maybe DBConnection is not necessary for a ClickHouse client.

And it doesn't seem like any other adapter needs a handle_info since that issue hasn't been brought up before.
So I'll revert it to avoid complicating DBConnection unnecessarily.

Sorry!

ruslandoga added a commit to ruslandoga/db_connection that referenced this pull request Dec 19, 2024
josevalim pushed a commit that referenced this pull request Dec 19, 2024
* Revert "Document handle_info/2 (#317)"

This reverts commit 4776530.

* Revert "Proxy info messages to the adapter (#316)"

This reverts commit 5d088f7.
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

Successfully merging this pull request may close these issues.

2 participants