Skip to content

Add Config.EagerConnect, so DialConfig can report a failure to connect - #76

Open
christhomas wants to merge 1 commit into
secsy:masterfrom
antimatter-studios:cth/eager-connect-upstream
Open

Add Config.EagerConnect, so DialConfig can report a failure to connect#76
christhomas wants to merge 1 commit into
secsy:masterfrom
antimatter-studios:cth/eager-connect-upstream

Conversation

@christhomas

Copy link
Copy Markdown

Fixes #35.

DialConfig is named like every other Dial in Go and behaves unlike them — it builds a client without connecting. Reproducing what the reporter hit:

DialConfig("127.0.0.1:62628")  ->  client, err = <nil>
first operation                ->  connection refused

A refused port, an unreachable host or a wrong password are reported by whatever operation happens to run first — or by nothing at all, if the caller checks the error DialConfig returned and carries on.

EagerConnect opens one connection and logs in before returning, so both kinds of failure come back from DialConfig. The connection is handed back to the pool rather than discarded, so the check costs a round trip and not a connection.

Why a flag and not a change to DialConfig

You wrote in the issue:

Dial is a misnomer since it doesn't synchronously attempt to open a connection like other Dials in in go. Perhaps better documentation for Dial would help. I plan to do a "v2" release at some point to fix this and other issues in the public API.

Agreed that changing DialConfig itself is a v2 matter — callers rely on it being cheap. This is the opt-in version, defaulting to false, so the behaviour is available to anyone who wants it without spending the break. If v2 makes it the default, the field goes away with nothing else to unwind.

Concretely, it removes a workaround: a downstream FTP driver of ours calls Getwd() immediately after DialConfig for no reason other than to make a bad host fail at mount time.

Tests

eager_connect_test.go — a refused port (no server needed; it binds a port and releases it, rather than guessing a number that might be filtered and hang), a wrong password, that the default is still lazy, and that the connection the check opens is not leaked.

Independent of #71, #72, #73 and #75.

Fixes secsy#35.

DialConfig is named like every other Dial in Go and behaves unlike them:
it builds a client without connecting. A refused port, an unreachable
host or a wrong password are therefore reported by whatever operation
happens to run first — or by nothing at all, if the caller checked the
error DialConfig returned and carried on, which is what the reporter did.

    DialConfig("127.0.0.1:62628")  ->  client, err = <nil>
    first operation               ->  connection refused

EagerConnect opens one connection and logs in before returning, so both
kinds of failure come back from DialConfig. The connection is returned to
the pool rather than discarded, so the check costs a round trip and not a
connection.

Opt-in, defaulting to false, because changing DialConfig itself would
break callers who rely on it being cheap — and the maintainer has said
this belongs to a v2. This gets the behaviour to anyone who wants it now
without spending that.

Red before green: the bug was reproduced first (DialConfig returning a
nil error for a port nothing was listening on), and the tests cover a
refused port, a wrong password, that the default is still lazy, and that
the connection opened by the check is not leaked.
@christhomas christhomas mentioned this pull request Aug 26, 2026
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.

No error when unable to connect

1 participant