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]