Aetherance commented on code in PR #3305:
URL: https://github.com/apache/dubbo-go/pull/3305#discussion_r3292990781
##########
cluster/router/tag/router.go:
##########
@@ -157,3 +172,269 @@ func parseRoute(routeContent string)
(*global.RouterConfig, error) {
}
return routerConfig, nil
}
+
+func (p *PriorityRouter) Name() string {
+ return "tag"
+}
+
+func (p *PriorityRouter) ShouldPool() bool {
+ return true
+}
+
+func (p *PriorityRouter) Pool(invokers []base.Invoker) (router.AddrPool,
router.AddrMetadata) {
+ pool := make(router.AddrPool)
+ for i, invoker := range invokers {
+ url := invoker.GetURL()
+ upsertBM(pool, "*", i)
+ tag := url.GetParam(constant.Tagkey, "")
+ upsertBM(pool, "tag\x00"+tag, i)
+ addr := url.Location
+ if addr != "" {
+ upsertBM(pool, "addr\x00"+addr, i)
+ if idx := strings.LastIndex(addr, ":"); idx > 0 {
+ upsertBM(pool, "port\x00"+addr[idx+1:], i)
+ }
+ }
+ for _, key := range []string{"version", "group"} {
+ if v := url.GetParam(key, ""); v != "" {
+ upsertBM(pool, "param\x00"+key+"\x00"+v, i)
+ } else {
+ upsertBM(pool, "param\x00"+key+"\x00\x00", i)
+ }
+ }
+ }
+ return pool, nil
+}
+
+func (p *PriorityRouter) SetCache(cache router.Cache) {
+ p.cache = cache
+}
+
+func (p *PriorityRouter) routeWithPool(invokers []base.Invoker, pool
router.AddrPool, url *common.URL, invocation base.Invocation) []base.Invoker {
+ tag := invocation.GetAttachmentWithDefaultValue(constant.Tagkey,
url.GetParam(constant.Tagkey, ""))
+
+ application := invokers[0].GetURL().GetParam(constant.ApplicationKey,
"")
+ key := strings.Join([]string{application,
constant.TagRouterRuleSuffix}, "")
+ value, ok := p.routerConfigs.Load(key)
+ if !ok {
+ return collectInvokers(invokers, p.staticTagMatchBM(pool, tag,
url, invocation))
+ }
+ routerCfg := value.(global.RouterConfig)
+ enabled := routerCfg.Enabled == nil || *routerCfg.Enabled
+ valid := (routerCfg.Valid != nil && *routerCfg.Valid) ||
(routerCfg.Valid == nil && len(routerCfg.Tags) > 0)
+ if !enabled || !valid {
+ return collectInvokers(invokers, p.staticTagMatchBM(pool, tag,
url, invocation))
+ }
+ if tag == "" {
+ return collectInvokers(invokers, p.emptyTagMatchBM(pool,
routerCfg))
+ }
+ bm := p.requestTagMatchBM(pool, url, invocation, routerCfg, tag)
+ if bm == nil {
+ return requestTag(invokers, url, invocation, routerCfg, tag)
+ }
+ return collectInvokers(invokers, bm)
+}
+
+func (p *PriorityRouter) staticTagMatchBM(pool router.AddrPool, tag string,
url *common.URL, invocation base.Invocation) *roaring.Bitmap {
+ if tag != "" {
+ if bm := pool["tag\x00"+tag]; bm != nil && !bm.IsEmpty() {
+ return bm
+ }
+ if requestIsForce(url, invocation) {
+ return nil
+ }
+ }
+ return pool["tag\x00"]
+}
+
+func (p *PriorityRouter) requestTagMatchBM(pool router.AddrPool, url
*common.URL, invocation base.Invocation,
+ cfg global.RouterConfig, tag string) *roaring.Bitmap {
+ var (
+ addresses []string
+ match []*common.ParamMatch
+ )
+ for _, tagCfg := range cfg.Tags {
+ if tagCfg.Name == tag {
+ addresses = tagCfg.Addresses
+ match = tagCfg.Match
+ break
+ }
+ }
+
+ var resultBM *roaring.Bitmap
+ if len(match) != 0 {
+ resultBM = p.matchBM(pool, match)
+ } else if len(addresses) != 0 {
+ resultBM = p.addressesBM(pool, addresses)
+ } else {
+ resultBM = pool["tag\x00"+tag]
+ }
+
+ if (cfg.Force != nil && *cfg.Force) || requestIsForce(url, invocation) {
+ return resultBM
+ }
+ if resultBM != nil && !resultBM.IsEmpty() {
+ return resultBM
+ }
+
+ emptyBM := pool["tag\x00"]
+ if emptyBM == nil {
+ return nil
+ }
+ if len(addresses) == 0 {
+ return emptyBM
+ }
+ addrBM := p.addressesBM(pool, addresses)
+ if addrBM != nil && !addrBM.IsEmpty() {
+ allBM := pool["*"]
+ if allBM != nil {
+ result := allBM.Clone()
+ result.AndNot(addrBM)
+ return result
+ }
+ }
+ return pool["*"]
Review Comment:
Fixed: in the non-cache path, the requestTag failover logic incorrectly
excluded addresses from the full invoker set instead of the already-filtered
no-tag providers when calling `filterInvokers(invokers, addresses, ...)`;
symmetrically, the cache path incorrectly used `pool["*"]` (full bitmap)
instead of `pool[PoolKeyTagPrefix]` (no-tag bitmap). Commit 6afda5f0 fixes both
issues: the non-cache path now uses `filterInvokers(result, ...)`, and the
cache path now uses `emptyBM.Clone()`.`AndNot(addrBM)`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]