feat!: Use a radix trie for route matching - #628
Conversation
|
| Project | cot |
| Branch | elijah/router-trie |
| Testbed | github-ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result milliseconds (ms) (Result Δ%) | Upper Boundary milliseconds (ms) (Limit %) |
|---|---|---|---|
| empty_router/empty_router | 📈 view plot 🚷 view threshold | 14.14 ms(+62.95%)Baseline: 8.68 ms | 16.57 ms (85.32%) |
| json_api/json_api | 📈 view plot 🚷 view threshold | 1.14 ms(+8.23%)Baseline: 1.05 ms | 1.37 ms (82.96%) |
| nested_routers/nested_routers | 📈 view plot 🚷 view threshold | 1.09 ms(+11.01%)Baseline: 0.98 ms | 1.26 ms (86.86%) |
| single_root_route/single_root_route | 📈 view plot 🚷 view threshold | 1.03 ms(+8.99%)Baseline: 0.95 ms | 1.22 ms (84.64%) |
| single_root_route_burst/single_root_route_burst | 📈 view plot 🚷 view threshold | 18.29 ms(+7.00%)Baseline: 17.09 ms | 21.56 ms (84.83%) |
|
Should be rebased on and merged after #586 |
| fn register_apps(&self, apps: &mut AppBuilder, _context: &RegisterAppsContext) { | ||
| apps.register_with_views(App1, ""); | ||
| apps.register_with_views(App2, ""); | ||
| apps.register_with_views(App2, "/foo"); |
There was a problem hiding this comment.
Do we have any way of registering multiple routers at the same URL? This is an important feature - people might want to merge different routers at the same base URL.
If matchit doesn't let us do that because it detects a conflict, we should merge the routers. I'm not sure if we should have separate methods to do that explicitly, or keep the implicit behavior - I'll let you decide.
| use thiserror::Error; | ||
| use tracing::debug; | ||
|
|
||
| const PATH_MATCHER_ERROR_PREFIX: &str = "route conflict error:"; |
There was a problem hiding this comment.
This is not really "conflict" in most cases, is it? For instance, a numeral-only parameter name doesn't really conflict with anything. I think this error message is misleading.
| /// Panics when a url string could not be parsed into a [`Route`] | ||
| #[must_use] | ||
| pub fn with_urls<T: Into<Vec<Route>>>(urls: T) -> Self { | ||
| match Self::try_with_urls(urls) { |
| password: &str, | ||
| ) -> Result<(), Box<dyn Error>> { | ||
| driver.goto(&format!("{}/admin/", server.url())).await?; | ||
| driver.goto(&format!("{}/admin", server.url())).await?; |
There was a problem hiding this comment.
Where is the change coming from? If there's a change in trailing slash handling coming from the migration, I think we should consistently use trailing slashes for URLs.
| //! # let mut client = cot::test::Client::new(ApiProject).await; | ||
| //! # | ||
| //! # let response = client.get("/swagger/").await?; | ||
| //! # let response = client.get("/swagger").await?; |
There was a problem hiding this comment.
Same here, we should probably modify the URL routes to include the trailing slashes.
Description
The current router implementation uses a
Vecto store routers, which has some real limitations. For example, using a vec meant route conflict detection was cumbersome and hacky to get right. Using a Radix trie is the right data structure for this problem. This PR delegates the core Trie logic to the matchit crate. We still keep our business logic in a light wrapper over the Matchit Router.Breaking Changes
url_prefixwill failType of change