Skip to content

Bound SQL Browser lookup and fall back to configured port - #187

Open
goodcomm74 wants to merge 4 commits into
elixir-ecto:masterfrom
goodcomm74:fix/sql-browser-timeout-port-fallback
Open

Bound SQL Browser lookup and fall back to configured port#187
goodcomm74 wants to merge 4 commits into
elixir-ecto:masterfrom
goodcomm74:fix/sql-browser-timeout-port-fallback

Conversation

@goodcomm74

Copy link
Copy Markdown

Summary

  • bound named-instance SQL Browser UDP receive with a configurable timeout
  • always close the UDP socket and return structured errors for malformed/send/receive failures
  • fall back to the configured TCP port when instance discovery fails
  • validate the SQL Browser declared response length

Why

gen_udp.recv/2 has no timeout, so a lost SQL Browser response can leave a DBConnection worker stuck indefinitely and prevent reconnect backoff from running. A configured fixed port is useful as a recovery path when UDP discovery is unavailable.

Tests

  • 10 focused instance tests pass
  • real UDP blackhole returns within the configured bound
  • Protocol attempts a real TCP listener on the configured fallback port
  • malformed and declared-length mismatch responses fall back safely

The fallback remains opt-in: without :port, discovery errors are returned as before.

@mjaric mjaric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi @goodcomm74 ,

Thank you for your contribution. The PR already looks great and with just few more adjustments it will be perfect. Could you please look into my comments and do this micro changes. Once done I will be more than happy to merge this into master branch and make release.

Thank you!

Comment thread lib/tds/instance.ex
end

defp instance_timeout(opts) do
case Keyword.get(opts, :instance_timeout, @default_timeout) do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

:instance_timeout is not documented, could you please add it to README.md in Configuration section. Mention default value too.

Comment thread lib/tds/instance.ex

defp browser_port(opts) do
opts
|> Keyword.get(:instance_browser_port, @default_browser_port)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

instance_browser_port sa as for instance_timeout, please document it in README.md

Comment thread lib/tds/protocol.ex

@type t :: %__MODULE__{
sock: nil | sock,
usock: nil | pid,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All usages of usock are removed from code, please remove it from type definition

Suggested change

Comment thread lib/tds/protocol.ex
}

defstruct sock: nil,
usock: nil,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All usages of usock are removed from code, please remove it from structure definition.

Suggested change

Comment thread lib/tds/instance.ex
end

defp find_instance([], _instance) do
error("SQL Server Browser returned a malformed response")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
error("SQL Server Browser returned a malformed response")
error("No instances advertised")

Probably better message

Comment thread lib/tds/instance.ex
defp normalize_port(port, label) when is_binary(port) do
case Integer.parse(String.trim(port)) do
{port, ""} when port in 1..65_535 -> {:ok, port}
_other -> error("#{label} is invalid: #{inspect(port)}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

normalize_port/2 now rejects values like "15433x" that the old code silently prefix-parsed. Nice fix, just add a line to the docs and CHANGELOG.md so it doesn't surprise anyone.

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