聊聊dubbo-go-proxy的Route


本文摘自网络,作者,侵删。

本文主要研究一下dubbo-go-proxy的Route

Route

dubbo-go-proxy/pkg/router/route.go

// Route defines the tree of router APIs
type Route struct {
    lock         sync.RWMutex
    tree         *avltree.Tree
    wildcardTree *avltree.Tree
}

// NewRoute returns an empty router tree
func NewRoute() *Route {
    return &Route{
        tree:         avltree.NewWithStringComparator(),
        wildcardTree: avltree.NewWithStringComparator(),
    }
}
Route定义了lock、tree、wildcardTree属性,其NewRoute方法用于创建Route

PutAPI

dubbo-go-proxy/pkg/router/route.go

// PutAPI puts an api into the resource
func (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)

UpdateAPI

dubbo-go-proxy/pkg/router/route.go

// UpdateAPI update the api method in the existing router node
func (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]

FindAPI

dubbo-go-proxy/pkg/router/route.go

// FindAPI returns the api that meets the
func (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

findNode

dubbo-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方法查找

searchWildcard

dubbo-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。

doc

  • dubbo-go-proxy

本文来自:51CTO博客

感谢作者:mb601ce0d29b15f

查看原文:聊聊dubbo-go-proxy的Route

相关阅读 >>

Golang如何利用多核

Go语言反射的使用

手撸Golang Go与微服务 聚合模式

手撸Golang 行为型设计模式 观察者模式

Gocn酷Go推荐】Go程序配置利器-viper库

清晰架构(clean architecture)的Go微服务: 程序设计

Go defer(Go延迟函数)介绍

Golang如何打包在linux上部署

了解学习Golang类型断言

Golang阿里云api请求鉴权

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...