Make Router faster to clone (#1123)

* Make `Router` faster to clone

* changelog

* Update axum/src/routing/mod.rs

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>

* fix

* Update axum/src/routing/mod.rs

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
This commit is contained in:
David Pedersen 2022-06-27 11:00:19 +02:00 committed by GitHub
parent 523c7fed88
commit cb207472f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 8 deletions

View file

@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased
- None.
- **fixed:** Make `Router` cheaper to clone ([#1123])
[#1123]: https://github.com/tokio-rs/axum/pull/1123
# 0.5.9 (20. June, 2022)

View file

@ -64,7 +64,7 @@ impl RouteId {
/// The router type for composing handlers and services.
pub struct Router<B = Body> {
routes: HashMap<RouteId, Endpoint<B>>,
node: Node,
node: Arc<Node>,
fallback: Fallback<B>,
nested_at_root: bool,
}
@ -73,7 +73,7 @@ impl<B> Clone for Router<B> {
fn clone(&self) -> Self {
Self {
routes: self.routes.clone(),
node: self.node.clone(),
node: Arc::clone(&self.node),
fallback: self.fallback.clone(),
nested_at_root: self.nested_at_root,
}
@ -162,9 +162,12 @@ where
Err(service) => Endpoint::Route(Route::new(service)),
};
if let Err(err) = self.node.insert(path, id) {
let mut node =
Arc::try_unwrap(Arc::clone(&self.node)).unwrap_or_else(|node| (*node).clone());
if let Err(err) = node.insert(path, id) {
self.panic_on_matchit_error(err);
}
self.node = Arc::new(node);
self.routes.insert(id, service);
@ -211,12 +214,12 @@ where
panic!("Cannot nest `Router`s that has a fallback");
}
for (id, nested_path) in node.route_id_to_path {
let route = routes.remove(&id).unwrap();
let full_path: Cow<str> = if &*nested_path == "/" {
for (id, nested_path) in &node.route_id_to_path {
let route = routes.remove(id).unwrap();
let full_path: Cow<str> = if &**nested_path == "/" {
path.into()
} else if path == "/" {
(&*nested_path).into()
(&**nested_path).into()
} else if let Some(path) = path.strip_suffix('/') {
format!("{}{}", path, nested_path).into()
} else {
@ -632,6 +635,7 @@ impl<B> fmt::Debug for Endpoint<B> {
}
#[test]
#[allow(warnings)]
fn traits() {
use crate::test_helpers::*;
assert_send::<Router<()>>();