Repository navigation
feat(volo-http): track matched route patterns - #675
Open
Joshuahoky wants to merge 3 commits into
Open
Joshuahoky wants to merge 3 commits into
Joshuahoky wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #675 +/- ##
==========================================
+ Coverage 61.68% 62.42% +0.74%
==========================================
Files 167 167
Lines 22604 22786 +182
==========================================
+ Hits 13943 14225 +282
+ Misses 8661 8561 -100 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Joshuahoky
force-pushed
the
feat/http-matched-path
branch
from
October 9, 2026 08:47
79edccd to
a9cdcac
Compare
Collaborator
|
Benchmark in my env: It looks OK. |
shenyj3
previously approved these changes
Oct 12, 2026
junliurs
reviewed
Oct 13, 2026
Contributor
There was a problem hiding this comment.
- 两套并行表:
Router同时维护routes: HashMap<RouteId, Endpoint>与patterns: HashMap<RouteId, FastStr>,同一 uri 分三处存(matchit 树、Matcher.matches、Router.patterns),每个route/nest/merge都要把self.patterns.insert(...)跟在self.matcher.insert(...)旁边手写一遍,三处易失步。 - 运行时字符串拼接:因为
nest是运行时委托(StripPrefix 层),MatchedPath::record里用outer.0.to_string() + pattern逐层拼前缀——每层一次分配、整串重拷,k 层嵌套为 O(k) 次分配、O(k²) 字节拷贝,且只在多级嵌套时才明显。 - 第二次 hash:
call里先routes.get拿 handler,再patterns.get拿样式——对同一条请求做两次 HashMap 查询。
改动(均在 volo-http/src/server/route/router.rs)
patterns: HashMap<RouteId, FastStr>字段删除,合并进routes:
routes: HashMap<RouteId, (Endpoint<B, E>, FastStr)>,handler 与 pattern 打包一处。route():routes.insert(id, (Endpoint::MethodRouter(...), FastStr::new(uri))),单次插入。nest():入参改mut router,构建期把嵌套前缀(去尾部/)预拼进内层每个 pattern(如/api/{version}/items/{id}),再nest_route。nest_route():nest 自身 route 的 pattern 即为前缀;routes.insert(id, (Endpoint::Service(...), FastStr::new(prefix.trim_end_matches('/'))))。merge()/layer()/new():同步去掉patterns字段及相关逻辑(merge 直接搬 tuple routes,删掉原patterns.drain循环)。call()热路径由:
“routes.get拿 handler +patterns.get拿样式 +record运行时拼接”
降为:
“一次self.routes.get(matched.value)解出(route, pattern)+ 一行cx.extensions_mut().insert(MatchedPath(pattern.clone()))”。- 删除
MatchedPath::recordhelper(to_string() + pattern的拼接函数),as_str/into_inner/Deref/AsRef保留。
junliurs
approved these changes
Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Currently, requests use the raw URL path for logging and metrics, which can lead to high cardinality when paths contain dynamic parameters.
For example, requests to /users/123 and /users/456 should be associated with the same route pattern, /users/{id}.
Solution
This change adds MatchedPath to identify requests by their registered route patterns instead.