mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-12 15:02:32 +00:00
fix(meta): preserve legacy retry hints in instruction replies
Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
@@ -49,7 +49,7 @@ pub struct InstructionError {
|
||||
pub message: String,
|
||||
/// Retry hint serialized as a string.
|
||||
#[serde(
|
||||
serialize_with = "RetryHint::serialize_as_str",
|
||||
serialize_with = "InstructionError::serialize_retry_hint",
|
||||
deserialize_with = "RetryHint::deserialize_from_str"
|
||||
)]
|
||||
pub retry_hint: RetryHint,
|
||||
@@ -108,6 +108,18 @@ impl InstructionError {
|
||||
retry_hint: error.retry_hint(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Keeps instruction replies readable by peers that only know the legacy hints.
|
||||
fn serialize_retry_hint<S>(hint: &RetryHint, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let hint = match hint {
|
||||
RetryHint::RetryAfterRouteRefresh => RetryHint::Retryable,
|
||||
hint => *hint,
|
||||
};
|
||||
RetryHint::serialize_as_str(&hint, serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for InstructionError {
|
||||
@@ -1450,6 +1462,26 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_instruction_error_route_refresh_compatibility() {
|
||||
let error = InstructionError::new(
|
||||
StatusCode::RegionNotFound,
|
||||
"region not found",
|
||||
RetryHint::RetryAfterRouteRefresh,
|
||||
);
|
||||
let serialized = serde_json::to_string(&error).unwrap();
|
||||
assert_eq!(
|
||||
r#"{"code":4005,"message":"region not found","retry_hint":"retryable"}"#,
|
||||
serialized
|
||||
);
|
||||
let decoded: InstructionError = serde_json::from_str(&serialized).unwrap();
|
||||
assert_eq!(decoded.code, error.code);
|
||||
assert_eq!(decoded.message, error.message);
|
||||
assert_eq!(decoded.retry_hint, RetryHint::Retryable);
|
||||
assert_eq!(error.retry_hint, RetryHint::RetryAfterRouteRefresh);
|
||||
assert_eq!(error.retry_hint.as_str(), "retry_after_route_refresh");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_instruction_error_from_error() {
|
||||
let error = MockError::new(StatusCode::RegionNotFound);
|
||||
|
||||
Reference in New Issue
Block a user