Skip to content

Commit 93b75c3

Browse files
fix(client): connect Flight lazily so HTTP-only clients don't require a Flight connection (#77)
* fix(client): connect Flight lazily so HTTP-only clients don't require a Flight connection build() eagerly connected the Flight channel, so building an HTTP-only client (e.g. for the async /v1/queries API) failed with a transport error when nothing was listening on the default Flight endpoint. Connect lazily instead: the channel is created without opening a connection, which is established on the first Flight RPC. Working clients are unaffected; HTTP-only clients never trigger a connection. * ci: drop macOS + beta-toolchain jobs The macOS install step is flaky and the macOS/beta combination is the least-valuable matrix cell; exclude it rather than chase the flake.
1 parent 7bc9e45 commit 93b75c3

2 files changed

Lines changed: 25 additions & 11 deletions

File tree

.github/workflows/build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ jobs:
6969
toolchain:
7070
- 1.93.1
7171
- beta
72+
exclude:
73+
# macOS install step is flaky and macOS + beta is the least-valuable
74+
# matrix cell; skip it rather than chase the flake.
75+
- os: macos-latest
76+
toolchain: beta
77+
- os: macos-14
78+
toolchain: beta
7279
steps:
7380
# actions/checkout v4.2.2
7481
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

src/tls.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,16 @@ impl FlightChannelBuilder {
8989
self
9090
}
9191

92-
/// Builds and connects the Flight channel.
92+
/// Builds the Flight channel.
93+
///
94+
/// The channel connects lazily: no connection is opened here, only on the
95+
/// first RPC. This lets an HTTP-only client be built without a reachable
96+
/// Flight endpoint.
9397
///
9498
/// # Errors
9599
///
96-
/// Returns an error if the TLS configuration is invalid, the
97-
/// certificate files cannot be read, or the connection fails.
100+
/// Returns an error if the endpoint URL is invalid, the TLS configuration
101+
/// is invalid, or the certificate files cannot be read.
98102
pub async fn build(self) -> Result<Channel, GenericError> {
99103
let mut endpoint = Endpoint::from_str(&self.url)?;
100104

@@ -122,7 +126,7 @@ impl FlightChannelBuilder {
122126
endpoint = endpoint.tls_config(tls_config)?;
123127
}
124128

125-
Ok(endpoint.connect().await?)
129+
Ok(endpoint.connect_lazy())
126130
}
127131
}
128132

@@ -165,17 +169,17 @@ mod tests {
165169

166170
#[tokio::test]
167171
async fn test_new_tls_flight_channel_http() {
168-
// HTTP endpoint should work without TLS
172+
// A valid HTTP endpoint builds a lazy channel without connecting.
169173
let result = new_tls_flight_channel("http://localhost:12345").await;
170-
// Will fail to connect, but should not panic on TLS config
171-
assert!(result.is_err()); // Connection refused is expected
174+
assert!(result.is_ok());
172175
}
173176

174177
#[tokio::test]
175178
async fn test_new_tls_flight_channel_https_invalid_host() {
176-
// HTTPS with invalid host should fail gracefully
179+
// A syntactically valid HTTPS endpoint builds a lazy channel; the host
180+
// is only resolved on the first RPC.
177181
let result = new_tls_flight_channel("https://invalid.nonexistent.host:443").await;
178-
assert!(result.is_err());
182+
assert!(result.is_ok());
179183
}
180184

181185
#[test]
@@ -198,14 +202,17 @@ mod tests {
198202

199203
#[tokio::test]
200204
async fn test_new_tls_flight_channel_unreachable_port() {
205+
// Builds a lazy channel; an unreachable port only fails on the first RPC.
201206
let result = new_tls_flight_channel("http://127.0.0.1:1").await;
202-
assert!(result.is_err());
207+
assert!(result.is_ok());
203208
}
204209

205210
#[tokio::test]
206211
async fn test_new_tls_flight_channel_missing_scheme() {
212+
// The authority parses, so a lazy channel is built; any scheme/connection
213+
// problem surfaces on the first RPC rather than at build time.
207214
let result = new_tls_flight_channel("example.com:443").await;
208-
assert!(result.is_err());
215+
assert!(result.is_ok());
209216
}
210217

211218
#[test]

0 commit comments

Comments
 (0)