序
本文主要研究一下dubbo-go-proxy的Route
Routedubbo-go-proxy/pkg/router/route.go
// Route defines the tree of router APIstype Route struct { lock sync.RWMutex tree *avltree.Tree wildcardTree *avltree.Tree}// NewRoute returns an empty router treefunc NewRoute() *Route { return &Route{ tree: avltree.NewWithStringComparator(), wildcardTree: avltree.NewWithStringComparator(), }}
Route定義了lock、tree、wildcardTree屬性,其NewRoute方法用於建立Route
PutAPIdubbo-go-proxy/pkg/router/route.go
// PutAPI puts an api into the resourcefunc (rt *Route) PutAPI(api router.API) error { lowerCasePath := strings.ToLower(api.URLPattern) node, ok := rt.findNode(lowerCasePath) rt.lock.Lock() defer rt.lock.Unlock() if !ok { wildcard := strings.Contains(lowerCasePath, constant.PathParamIdentifier) rn := &Node{ fullPath: lowerCasePath, methods: map[config.HTTPVerb]*config.Method{api.Method.HTTPVerb: &api.Method}, wildcard: wildcard, headers: api.Headers, } if wildcard { rt.wildcardTree.Put(lowerCasePath, rn) } rt.tree.Put(lowerCasePath, rn) return nil } return node.putMethod(api.Method, api.Headers)}
PutAPI方法根據lowerCasePath去查詢node,若沒有找到則加鎖建立Node,然後放到tree中,若是path是wildcard的則也會加入到wildcardTree中;如果有找到則執行node.putMethod(api.Method, api.Headers)
UpdateAPIdubbo-go-proxy/pkg/router/route.go
// UpdateAPI update the api method in the existing router nodefunc (rt *Route) UpdateAPI(api router.API) error { node, found := rt.findNode(api.URLPattern) if found { if _, ok := node.methods[api.Method.HTTPVerb]; ok { rt.lock.Lock() defer rt.lock.Unlock() node.methods[api.Method.HTTPVerb] = &api.Method } } return nil}
UpdateAPI方法先根據api.URLPattern查詢node,若找不到返回nil,找到的話再去找node.methods[api.Method.HTTPVerb],若找到則將api.Method賦值給node.methods[api.Method.HTTPVerb]
FindAPIdubbo-go-proxy/pkg/router/route.go
// FindAPI returns the api that meets thefunc (rt *Route) FindAPI(fullPath string, httpverb config.HTTPVerb) (*router.API, bool) { if n, found := rt.findNode(fullPath); found { rt.lock.RLock() defer rt.lock.RUnlock() if method, ok := n.methods[httpverb]; ok { return &router.API{ URLPattern: n.fullPath, Method: *method, Headers: n.headers, }, ok } } return nil, false}
FindAPI方法先透過findNode找node,再透過node.methods[httpverb]找method
findNodedubbo-go-proxy/pkg/router/route.go
func (rt *Route) findNode(fullPath string) (*Node, bool) { lowerPath := strings.ToLower(fullPath) var n interface{} var found bool if n, found = rt.searchWildcard(lowerPath); !found { rt.lock.RLock() defer rt.lock.RUnlock() if n, found = rt.tree.Get(lowerPath); !found { return nil, false } } return n.(*Node), found}
findNode方法透過searchWildcard來查詢node,找不到則從node的tree.Get方法查詢
searchWildcarddubbo-go-proxy/pkg/router/route.go
func (rt *Route) searchWildcard(fullPath string) (*Node, bool) { rt.lock.RLock() defer rt.lock.RUnlock() wildcardPaths := rt.wildcardTree.Keys() for _, p := range wildcardPaths { if wildcardMatch(p.(string), fullPath) != nil { n, ok := rt.wildcardTree.Get(p) return n.(*Node), ok } } return nil, false}
searchWildcard方法遍歷wildcardTree.Keys(),挨個執行wildcardMatch,若匹配到則透過wildcardTree.Get(p)來獲取node
小結Route定義了lock、tree、wildcardTree屬性,其NewRoute方法用於建立Route;它提供了PutAPI、UpdateAPI、FindAPI等方法;裡頭實現使用的是avltree.Tree。
docdubbo-go-proxy- GC類壓力管道安裝資質辦理,氨製冷(冷庫)管道定期檢驗程序
- 幾種PCBA表面處理的類型
- 歌禮制藥-B(01672)宣佈口服PD-L1小分子抑制劑前藥ASC61 用於治療晚期實體瘤的美國I期臨床試驗完成首例患者給藥
- 深耕CRO服務領域 宣泰醫藥(688247.SH)擬首次公開發行4534萬股
- 壓力容器許可證資質辦理,鉻鉬鋼製壓力容器結構設計規定
- 家裡有點地,這種果樹種上兩棵,栽到花盆裡,夏天就能結果子
- 家裡養株“大將軍”蘭花,花色喜慶,花大如盆,打理很簡單
- 庫存飆升!韓國半導體庫存激增80%
- 多點DMALL合夥人劉桂海:多點DMALL實踐實體零售數字化轉型
- 豬各階段拉稀的原因和解決方案,這篇文章告訴你答案,值得收藏