maxingg commented on code in PR #496:
URL: https://github.com/apache/dubbo-go-pixiu/pull/496#discussion_r970799652


##########
pixiu/pkg/filter/traffic/traffic.go:
##########
@@ -79,41 +91,88 @@ func (factory *FilterFactory) Config() interface{} {
 }
 
 func (factory *FilterFactory) Apply() error {
-       initActions()
        return nil
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{}
-       f.Rules = factory.rulesMatch(ctx.Request.RequestURI)
+       f := &Filter{
+               weight: unInitialize,
+               record: map[string]bool{},
+       }
+       f.Rules = factory.rulesMatch(f, ctx.Request.RequestURI)
        chain.AppendDecodeFilters(f)
        return nil
 }
 
 func (f *Filter) Decode(ctx *http.HttpContext) filter.FilterStatus {
        if f.Rules != nil {
-               cluster := spilt(ctx.Request, f.Rules)
-               if cluster != nil {
-                       ctx.Route.Cluster = cluster.Name
-                       logger.Debugf("[dubbo-go-pixiu] execute traffic split 
to cluster %s", cluster.Name)
+               for _, wp := range f.Rules {
+                       result := f.traffic(wp, ctx)
+                       if result {
+                               ctx.Route.Cluster = wp.Cluster.Name
+                               logger.Debugf("[dubbo-go-pixiu] execute traffic 
split to cluster %s", wp.Cluster.Name)
+                               break
+                       }
                }
        } else {
                logger.Warnf("[dubbo-go-pixiu] execute traffic split fail 
because of empty rules.")
        }
        return filter.Continue
 }
 
-func (factory *FilterFactory) rulesMatch(path string) 
map[CanaryHeaders]*Cluster {
+func (f *Filter) traffic(c *ClusterWrapper, ctx *http.HttpContext) bool {
+       if f.weight == unInitialize {
+               rand.Seed(time.Now().UnixNano())
+               f.weight = rand.Intn(100) + 1
+       }
+
+       res := false
+       if c.header != "" {
+               res = headerSpilt(ctx.Request, c.header)
+       } else if res == false && c.weightFloor != -1 && c.weightCeil != -1 {
+               res = weightSpilt(f.weight, c.weightFloor, c.weightCeil)
+       }
+       return res
+}
+
+func (factory *FilterFactory) rulesMatch(f *Filter, path string) 
[]*ClusterWrapper {
        clusters := factory.cfg.Traffics
 
        if clusters != nil {
-               mp := make(map[CanaryHeaders]*Cluster)
-               for i := range clusters {
-                       if strings.HasPrefix(clusters[i].Router, path) {
-                               mp[clusters[i].Model] = clusters[i]
+               rules := make([]*ClusterWrapper, 0)
+               up := 0
+               for _, cluster := range clusters {
+                       if strings.HasPrefix(path, cluster.Router) {
+                               wp := &ClusterWrapper{
+                                       Cluster:     cluster,
+                                       header:      "",
+                                       weightCeil:  -1,
+                                       weightFloor: -1,
+                               }
+                               if cluster.CanaryByHeader != "" {
+                                       if f.record[cluster.CanaryByHeader] {
+                                               panic("Duplicate 
canary-by-header values")
+                                       } else {
+                                               
f.record[cluster.CanaryByHeader] = true
+                                               wp.header = 
cluster.CanaryByHeader
+                                       }
+                               }
+                               if cluster.CanaryWeight != "" {
+                                       val, err := 
strconv.Atoi(cluster.CanaryWeight)
+                                       if err != nil || val <= 0 {
+                                               panic(fmt.Sprintf("Wrong 
canary-weight value: %v", cluster.CanaryWeight))
+                                       }
+                                       wp.weightFloor = up
+                                       up += val
+                                       if up > 100 {
+                                               panic("Total canary-weight more 
than 100")

Review Comment:
   I' ll handle with log.Errorf



##########
pixiu/pkg/filter/traffic/traffic.go:
##########
@@ -79,41 +91,88 @@ func (factory *FilterFactory) Config() interface{} {
 }
 
 func (factory *FilterFactory) Apply() error {
-       initActions()
        return nil
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{}
-       f.Rules = factory.rulesMatch(ctx.Request.RequestURI)
+       f := &Filter{
+               weight: unInitialize,
+               record: map[string]bool{},
+       }
+       f.Rules = factory.rulesMatch(f, ctx.Request.RequestURI)
        chain.AppendDecodeFilters(f)
        return nil
 }
 
 func (f *Filter) Decode(ctx *http.HttpContext) filter.FilterStatus {
        if f.Rules != nil {
-               cluster := spilt(ctx.Request, f.Rules)
-               if cluster != nil {
-                       ctx.Route.Cluster = cluster.Name
-                       logger.Debugf("[dubbo-go-pixiu] execute traffic split 
to cluster %s", cluster.Name)
+               for _, wp := range f.Rules {
+                       result := f.traffic(wp, ctx)
+                       if result {
+                               ctx.Route.Cluster = wp.Cluster.Name
+                               logger.Debugf("[dubbo-go-pixiu] execute traffic 
split to cluster %s", wp.Cluster.Name)
+                               break
+                       }
                }
        } else {
                logger.Warnf("[dubbo-go-pixiu] execute traffic split fail 
because of empty rules.")
        }
        return filter.Continue
 }
 
-func (factory *FilterFactory) rulesMatch(path string) 
map[CanaryHeaders]*Cluster {
+func (f *Filter) traffic(c *ClusterWrapper, ctx *http.HttpContext) bool {
+       if f.weight == unInitialize {
+               rand.Seed(time.Now().UnixNano())
+               f.weight = rand.Intn(100) + 1
+       }
+
+       res := false
+       if c.header != "" {
+               res = headerSpilt(ctx.Request, c.header)
+       } else if res == false && c.weightFloor != -1 && c.weightCeil != -1 {

Review Comment:
   Okay



-- 
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]

Reply via email to