feat(operator): retry failed writes with refreshed partitions (#9542)

* feat(operator): retry failed writes with refreshed partitions

Signed-off-by: WenyXu <wenymedia@gmail.com>

* style(operator): simplify retry test type references

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(operator): clarify write request rebuilding names

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(operator): encapsulate write retry attempts

Signed-off-by: WenyXu <wenymedia@gmail.com>

* style(operator): group inserter configuration methods

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(operator): share routed peers and separate retry decisions

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(operator): avoid temporary write routing allocations

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
Weny Xu
2026-10-13 06:02:43 +00:00
committed by GitHub
parent 18634e17bb
commit d86741d0ad
13 changed files with 1958 additions and 117 deletions
+3
View File
@@ -22,6 +22,9 @@ use crate::cluster::NodeInfo;
use crate::error::Error;
use crate::{DatanodeId, FlownodeId};
/// Shared reference to a [`Peer`].
pub type PeerRef = Arc<Peer>;
/// [`PeerResolver`] provides methods to look up peer information by node ID.
///
/// This trait allows resolving both datanode and flownode peers, regardless of their current activity status.
+32 -1
View File
@@ -114,15 +114,25 @@ pub fn convert_to_region_leader_map(region_routes: &[RegionRoute]) -> HashMap<Re
.collect::<HashMap<_, _>>()
}
/// Returns the leader of the first route matching the region number.
pub fn find_region_leader(
region_routes: &[RegionRoute],
region_number: RegionNumber,
) -> Option<Peer> {
find_region_leader_ref(region_routes, region_number).cloned()
}
/// Borrows the leader of the first route matching the region number.
///
/// Returns `None` if no route matches or the first matching route has no leader.
pub fn find_region_leader_ref(
region_routes: &[RegionRoute],
region_number: RegionNumber,
) -> Option<&Peer> {
region_routes
.iter()
.find(|x| x.region.id.region_number() == region_number)
.and_then(|r| r.leader_peer.as_ref())
.cloned()
}
/// Returns the region numbers of the leader regions on the target datanode.
@@ -442,6 +452,27 @@ mod tests {
}
}
#[test]
fn test_find_region_leader() {
let mut routes = vec![
new_test_region_route(RegionId::new(1, 1)),
new_test_region_route(RegionId::new(1, 1)),
];
routes[1].leader_peer = Some(Peer::new(2, "a2"));
assert_eq!(
find_region_leader_ref(&routes, 1),
routes[0].leader_peer.as_ref()
);
assert_eq!(find_region_leader(&routes, 1), routes[0].leader_peer);
assert_eq!(find_region_leader_ref(&routes, 2), None);
assert_eq!(find_region_leader(&routes, 2), None);
routes[0].leader_peer = None;
assert_eq!(find_region_leader_ref(&routes, 1), None);
assert_eq!(find_region_leader(&routes, 1), None);
}
#[test]
fn test_leader_is_downgraded() {
let mut region_route = RegionRoute {