From 939e6de8e3a17d5d24d7348060bfbd30443214c2 Mon Sep 17 00:00:00 2001 From: Mark Logan Date: Thu, 1 Feb 2024 12:24:55 -0800 Subject: [PATCH] Use BTreeMap for deterministic drop order Because of the use of the static ROUTE_ID counter, the internal ordering of the HashMap depends on when the routes are added to the Router. Routes can cause arbitrary code to run when they are dropped, so this is an unwanted source of non determinism. (Even controlling the HashMap's RandomState will not help in this case). A BTreeMap guarantees routes are dropped in the order they were created, and. I also suspect it will be no slower (and maybe faster) for small numbers of routes (the common case). This is not performance critical code in any case. --- crates/anemo/src/routing/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/anemo/src/routing/mod.rs b/crates/anemo/src/routing/mod.rs index b87a451e..137f6058 100644 --- a/crates/anemo/src/routing/mod.rs +++ b/crates/anemo/src/routing/mod.rs @@ -1,6 +1,11 @@ use crate::{Request, Response}; use bytes::Bytes; -use std::{collections::HashMap, convert::Infallible, fmt, sync::Arc}; +use std::{ + collections::{BTreeMap, HashMap}, + convert::Infallible, + fmt, + sync::Arc, +}; use tower::{ util::{BoxCloneService, Oneshot}, Service, @@ -30,7 +35,7 @@ impl RouteId { /// The router type for composing handlers and services. #[derive(Clone)] pub struct Router { - routes: HashMap, + routes: BTreeMap, matcher: RouteMatcher, fallback: Route, }