Skip to content

Commit a6bb187

Browse files
authored
fix(query): include node id in flight errors (#20177)
* fix(query): include node id in flight errors * fix(query): add operation to flight error context * fix(query): include flight client node in errors
1 parent a87c174 commit a6bb187

7 files changed

Lines changed: 315 additions & 82 deletions

File tree

src/query/service/src/clusters/cluster.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ use tokio::time::sleep as tokio_async_sleep;
7676
use tokio::time::sleep;
7777

7878
use crate::servers::flight::FlightClient;
79+
use crate::servers::flight::FlightOperation;
80+
use crate::servers::flight::add_flight_error_context;
7981
use crate::servers::flight::keep_alive::build_keep_alive_config;
8082

8183
pub struct ClusterDiscovery {
@@ -185,15 +187,20 @@ impl ClusterHelper for Cluster {
185187
let do_action_with_retry = {
186188
let config = GlobalConfig::instance();
187189
let flight_address = node.flight_address.clone();
190+
let node_id = node.id.clone();
188191
let node_secret = node.secret.clone();
189192

190193
async move {
191194
let mut attempt = 0;
192195

193196
loop {
194-
let mut conn =
195-
create_client(&config, &flight_address, flight_params.keep_alive)
196-
.await?;
197+
let mut conn = create_client(
198+
&config,
199+
&node_id,
200+
&flight_address,
201+
flight_params.keep_alive,
202+
)
203+
.await?;
197204
match conn
198205
.do_action::<_, Res>(
199206
path,
@@ -325,6 +332,7 @@ impl ClusterDiscovery {
325332
let start_at = Instant::now();
326333
if let Err(cause) = create_client(
327334
config,
335+
&node.id,
328336
&node.flight_address,
329337
FlightKeepAliveParams::default(),
330338
)
@@ -986,6 +994,7 @@ impl ClusterHeartbeat {
986994
#[async_backtrace::framed]
987995
pub async fn create_client(
988996
config: &InnerConfig,
997+
remote_node_id: &str,
989998
address: &str,
990999
keep_alive: FlightKeepAliveParams,
9911000
) -> Result<FlightClient> {
@@ -1004,15 +1013,27 @@ pub async fn create_client(
10041013
};
10051014
let keep_alive_config = build_keep_alive_config(keep_alive);
10061015

1007-
Ok(FlightClient::new(FlightServiceClient::new(
1008-
ConnectionFactory::create_rpc_channel(
1009-
address.to_owned(),
1010-
timeout,
1011-
rpc_tls_config,
1012-
keep_alive_config,
1016+
let channel = ConnectionFactory::create_rpc_channel(
1017+
address.to_owned(),
1018+
timeout,
1019+
rpc_tls_config,
1020+
keep_alive_config,
1021+
)
1022+
.await
1023+
.map_err(|error| {
1024+
add_flight_error_context(
1025+
ErrorCode::from(error),
1026+
FlightOperation::Connect,
1027+
&config.query.node_id,
1028+
remote_node_id,
10131029
)
1014-
.await?,
1015-
)))
1030+
})?;
1031+
1032+
Ok(FlightClient::new(
1033+
FlightServiceClient::new(channel),
1034+
&config.query.node_id,
1035+
remote_node_id,
1036+
))
10161037
}
10171038

10181039
#[derive(Clone, Copy, Debug)]

src/query/service/src/servers/flight/flight_client.rs

Lines changed: 114 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,58 @@ pub struct DoExchangeParams {
5353

5454
pub struct FlightClient {
5555
inner: FlightServiceClient<Channel>,
56+
local_node_id: String,
57+
remote_node_id: String,
58+
}
59+
60+
#[derive(Clone, Copy)]
61+
pub(crate) enum FlightOperation {
62+
Connect,
63+
DoAction,
64+
DoGet,
65+
DoExchange,
66+
}
67+
68+
impl FlightOperation {
69+
fn as_str(self) -> &'static str {
70+
match self {
71+
FlightOperation::Connect => "connect",
72+
FlightOperation::DoAction => "do_action",
73+
FlightOperation::DoGet => "do_get",
74+
FlightOperation::DoExchange => "do_exchange",
75+
}
76+
}
77+
}
78+
79+
pub(crate) fn add_flight_error_context(
80+
error: ErrorCode,
81+
operation: FlightOperation,
82+
local_node_id: &str,
83+
remote_node_id: &str,
84+
) -> ErrorCode {
85+
error.add_message_back(format!(
86+
"(flight {}, client={}, service={})",
87+
operation.as_str(),
88+
local_node_id,
89+
remote_node_id,
90+
))
5691
}
5792

5893
// TODO: Integration testing required
5994
impl FlightClient {
60-
pub fn new(mut inner: FlightServiceClient<Channel>) -> FlightClient {
95+
pub fn new(
96+
mut inner: FlightServiceClient<Channel>,
97+
local_node_id: impl Into<String>,
98+
remote_node_id: impl Into<String>,
99+
) -> FlightClient {
61100
inner = inner.max_decoding_message_size(usize::MAX);
62101
inner = inner.max_encoding_message_size(usize::MAX);
63102

64-
FlightClient { inner }
103+
FlightClient {
104+
inner,
105+
local_node_id: local_node_id.into(),
106+
remote_node_id: remote_node_id.into(),
107+
}
65108
}
66109

67110
#[async_backtrace::framed]
@@ -100,25 +143,51 @@ impl FlightClient {
100143
AsciiMetadataValue::from_str(&secret).unwrap(),
101144
);
102145

103-
let response = self.inner.do_action(request).await?;
146+
let response = self.inner.do_action(request).await.map_err(|status| {
147+
add_flight_error_context(
148+
ErrorCode::from(status),
149+
FlightOperation::DoAction,
150+
&self.local_node_id,
151+
&self.remote_node_id,
152+
)
153+
})?;
154+
155+
let response = response.into_inner().message().await.map_err(|status| {
156+
add_flight_error_context(
157+
ErrorCode::from(status),
158+
FlightOperation::DoAction,
159+
&self.local_node_id,
160+
&self.remote_node_id,
161+
)
162+
})?;
104163

105-
match response.into_inner().message().await? {
164+
match response {
106165
Some(response) => {
107166
let mut deserializer = serde_json::Deserializer::from_slice(&response.body);
108167
deserializer.disable_recursion_limit();
109168
let deserializer = serde_stacker::Deserializer::new(&mut deserializer);
110169

111170
Res::deserialize(deserializer).map_err(|cause| {
112-
ErrorCode::BadBytes(format!(
113-
"Response payload deserialize error while in {:?}, cause: {}",
114-
path, cause
115-
))
171+
add_flight_error_context(
172+
ErrorCode::BadBytes(format!(
173+
"Response payload deserialize error while in {:?}, cause: {}",
174+
path, cause
175+
)),
176+
FlightOperation::DoAction,
177+
&self.local_node_id,
178+
&self.remote_node_id,
179+
)
116180
})
117181
}
118-
None => Err(ErrorCode::EmptyDataFromServer(format!(
119-
"Can not receive data from flight server, action: {:?}",
120-
path
121-
))),
182+
None => Err(add_flight_error_context(
183+
ErrorCode::EmptyDataFromServer(format!(
184+
"Can not receive data from flight server, action: {:?}",
185+
path
186+
)),
187+
FlightOperation::DoAction,
188+
&self.local_node_id,
189+
&self.remote_node_id,
190+
)),
122191
}
123192
}
124193

@@ -138,7 +207,11 @@ impl FlightClient {
138207
)
139208
.await?;
140209

141-
let (notify, rx) = Self::streaming_receiver(streaming);
210+
let (notify, rx) = Self::streaming_receiver(
211+
streaming,
212+
self.local_node_id.clone(),
213+
self.remote_node_id.clone(),
214+
);
142215
Ok(FlightExchange::create_receiver(notify, rx))
143216
}
144217

@@ -154,12 +227,18 @@ impl FlightClient {
154227

155228
let streaming = self.get_streaming(request).await?;
156229

157-
let (notify, rx) = Self::streaming_receiver(streaming);
230+
let (notify, rx) = Self::streaming_receiver(
231+
streaming,
232+
self.local_node_id.clone(),
233+
self.remote_node_id.clone(),
234+
);
158235
Ok(FlightExchange::create_receiver(notify, rx))
159236
}
160237

161238
fn streaming_receiver(
162239
mut streaming: Streaming<FlightData>,
240+
local_node_id: String,
241+
remote_node_id: String,
163242
) -> (Arc<WatchNotify>, Receiver<Result<FlightData>>) {
164243
let (tx, rx) = async_channel::bounded(1);
165244
let notify = Arc::new(WatchNotify::new());
@@ -185,7 +264,13 @@ impl FlightClient {
185264
}
186265
}
187266
Err(status) => {
188-
let _ = tx.send(Err(ErrorCode::from(status))).await;
267+
let error = add_flight_error_context(
268+
ErrorCode::from(status),
269+
FlightOperation::DoGet,
270+
&local_node_id,
271+
&remote_node_id,
272+
);
273+
let _ = tx.send(Err(error)).await;
189274
break;
190275
}
191276
}
@@ -208,7 +293,12 @@ impl FlightClient {
208293
async fn get_streaming(&mut self, request: Request<Ticket>) -> Result<Streaming<FlightData>> {
209294
match self.inner.do_get(request).await {
210295
Ok(res) => Ok(res.into_inner()),
211-
Err(status) => Err(ErrorCode::from(status).add_message_back("(while in query flight)")),
296+
Err(status) => Err(add_flight_error_context(
297+
ErrorCode::from(status),
298+
FlightOperation::DoGet,
299+
&self.local_node_id,
300+
&self.remote_node_id,
301+
)),
212302
}
213303
}
214304

@@ -217,25 +307,26 @@ impl FlightClient {
217307
request_rx: Receiver<FlightData>,
218308
params: DoExchangeParams,
219309
) -> std::pin::Pin<
220-
Box<
221-
dyn std::future::Future<Output = std::result::Result<Streaming<FlightData>, Status>>
222-
+ Send
223-
+ '_,
224-
>,
310+
Box<dyn std::future::Future<Output = Result<Streaming<FlightData>>> + Send + '_>,
225311
> {
226312
Box::pin(async move {
227313
let mut request = Request::new(request_rx);
228314

229315
let params_json = serde_json::to_string(&params).map_err(|e| {
230-
Status::internal(format!("Failed to serialize DoExchangeParams: {}", e))
316+
ErrorCode::Internal(format!("Failed to serialize DoExchangeParams: {}", e))
231317
})?;
232318
if let Ok(value) = params_json.parse() {
233319
request.metadata_mut().insert("x-exchange-params", value);
234320
}
235321

236322
match self.inner.do_exchange(request).await {
237323
Ok(response) => Ok(response.into_inner()),
238-
Err(status) => Err(status),
324+
Err(status) => Err(add_flight_error_context(
325+
ErrorCode::from(status),
326+
FlightOperation::DoExchange,
327+
&self.local_node_id,
328+
&self.remote_node_id,
329+
)),
239330
}
240331
})
241332
}

src/query/service/src/servers/flight/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ pub mod v1;
2121
pub use flight_client::DoExchangeParams;
2222
pub use flight_client::FlightClient;
2323
pub use flight_client::FlightExchange;
24+
pub(crate) use flight_client::FlightOperation;
2425
pub use flight_client::FlightReceiver;
2526
pub use flight_client::FlightSender;
27+
pub(crate) use flight_client::add_flight_error_context;
2628
pub use flight_service::FlightService;

0 commit comments

Comments
 (0)