Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor slot chain mechanism and introduce slot order to rank #318

Merged
merged 7 commits into from
Nov 15, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ func (m *prepareSlotMock) Name() string {
return "mock-sentinel-prepare-slot"
}

func (m *prepareSlotMock) Order() uint32 {
return 0
}

func (m *prepareSlotMock) Prepare(ctx *base.EntryContext) {
m.Called(ctx)
return
Expand All @@ -29,6 +33,10 @@ func (m *mockRuleCheckSlot1) Name() string {
return "mock-sentinel-rule-check-slot1"
}

func (m *mockRuleCheckSlot1) Order() uint32 {
return 0
}

func (m *mockRuleCheckSlot1) Check(ctx *base.EntryContext) *base.TokenResult {
arg := m.Called(ctx)
return arg.Get(0).(*base.TokenResult)
Expand All @@ -42,6 +50,10 @@ func (m *mockRuleCheckSlot2) Name() string {
return "mock-sentinel-rule-check-slot2"
}

func (m *mockRuleCheckSlot2) Order() uint32 {
return 0
}

func (m *mockRuleCheckSlot2) Check(ctx *base.EntryContext) *base.TokenResult {
arg := m.Called(ctx)
return arg.Get(0).(*base.TokenResult)
Expand All @@ -55,6 +67,10 @@ func (m *statisticSlotMock) Name() string {
return "mock-sentinel-stat-check-slot"
}

func (m *statisticSlotMock) Order() uint32 {
return 0
}

func (m *statisticSlotMock) OnEntryPassed(ctx *base.EntryContext) {
m.Called(ctx)
return
Expand All @@ -74,10 +90,10 @@ func Test_entryWithArgsAndChainPass(t *testing.T) {
rcs1 := &mockRuleCheckSlot1{}
rcs2 := &mockRuleCheckSlot2{}
ssm := &statisticSlotMock{}
sc.AddStatPrepareSlotFirst(ps1)
sc.AddRuleCheckSlotFirst(rcs1)
sc.AddRuleCheckSlotFirst(rcs2)
sc.AddStatSlotFirst(ssm)
sc.AddStatPrepareSlot(ps1)
sc.AddRuleCheckSlot(rcs1)
sc.AddRuleCheckSlot(rcs2)
sc.AddStatSlot(ssm)

ps1.On("Prepare", mock.Anything).Return()
rcs1.On("Check", mock.Anything).Return(base.NewTokenResultPass())
Expand Down Expand Up @@ -111,10 +127,10 @@ func Test_entryWithArgsAndChainBlock(t *testing.T) {
rcs1 := &mockRuleCheckSlot1{}
rcs2 := &mockRuleCheckSlot2{}
ssm := &statisticSlotMock{}
sc.AddStatPrepareSlotFirst(ps1)
sc.AddRuleCheckSlotLast(rcs1)
sc.AddRuleCheckSlotLast(rcs2)
sc.AddStatSlotFirst(ssm)
sc.AddStatPrepareSlot(ps1)
sc.AddRuleCheckSlot(rcs1)
sc.AddRuleCheckSlot(rcs2)
sc.AddStatSlot(ssm)

blockType := base.BlockTypeFlow

Expand Down
26 changes: 13 additions & 13 deletions api/slot_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ func GlobalSlotChain() *base.SlotChain {

func BuildDefaultSlotChain() *base.SlotChain {
sc := base.NewSlotChain()
sc.AddStatPrepareSlotLast(stat.DefaultResourceNodePrepareSlot)

sc.AddRuleCheckSlotLast(system.DefaultAdaptiveSlot)
sc.AddRuleCheckSlotLast(flow.DefaultSlot)
sc.AddRuleCheckSlotLast(isolation.DefaultSlot)
sc.AddRuleCheckSlotLast(circuitbreaker.DefaultSlot)
sc.AddRuleCheckSlotLast(hotspot.DefaultSlot)

sc.AddStatSlotLast(stat.DefaultSlot)
sc.AddStatSlotLast(log.DefaultSlot)
sc.AddStatSlotLast(circuitbreaker.DefaultMetricStatSlot)
sc.AddStatSlotLast(hotspot.DefaultConcurrencyStatSlot)
sc.AddStatSlotLast(flow.DefaultStandaloneStatSlot)
sc.AddStatPrepareSlot(stat.DefaultResourceNodePrepareSlot)

sc.AddRuleCheckSlot(system.DefaultAdaptiveSlot)
sc.AddRuleCheckSlot(flow.DefaultSlot)
sc.AddRuleCheckSlot(isolation.DefaultSlot)
sc.AddRuleCheckSlot(circuitbreaker.DefaultSlot)
sc.AddRuleCheckSlot(hotspot.DefaultSlot)

sc.AddStatSlot(stat.DefaultSlot)
sc.AddStatSlot(log.DefaultSlot)
sc.AddStatSlot(circuitbreaker.DefaultMetricStatSlot)
sc.AddStatSlot(hotspot.DefaultConcurrencyStatSlot)
sc.AddStatSlot(flow.DefaultStandaloneStatSlot)
return sc
}

Expand Down
47 changes: 21 additions & 26 deletions core/base/slot_chain.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package base

import (
"sort"
"sync"

"github.com/alibaba/sentinel-golang/logging"
"github.com/alibaba/sentinel-golang/util"
"github.com/pkg/errors"
)

type NamedSlot interface {
type BaseSlot interface {
// Name returns its slot name which should not be the same as other slots.
Name() string

// Order returns the order value of slot.
// Slots will be sorted according to order value in increasing order.
Order() uint32
}

// StatPrepareSlot is responsible for some preparation before statistic
// For example: init structure and so on
type StatPrepareSlot interface {
NamedSlot
BaseSlot
louyuting marked this conversation as resolved.
Show resolved Hide resolved
// Prepare function do some initialization
// Such as: init statistic structure、node and etc
// The result of preparing would store in EntryContext
Expand All @@ -28,7 +33,7 @@ type StatPrepareSlot interface {
// RuleCheckSlot is rule based checking strategy
// All checking rule must implement this interface.
type RuleCheckSlot interface {
NamedSlot
BaseSlot
louyuting marked this conversation as resolved.
Show resolved Hide resolved
// Check function do some validation
// It can break off the slot pipeline
// Each TokenResult will return check result
Expand All @@ -39,7 +44,7 @@ type RuleCheckSlot interface {
// StatSlot is responsible for counting all custom biz metrics.
// StatSlot would not handle any panic, and pass up all panic to slot chain
type StatSlot interface {
NamedSlot
BaseSlot
louyuting marked this conversation as resolved.
Show resolved Hide resolved
// OnEntryPass function will be invoked when StatPrepareSlots and RuleCheckSlots execute pass
// StatSlots will do some statistic logic, such as QPS、log、etc
OnEntryPassed(ctx *EntryContext)
Expand Down Expand Up @@ -125,15 +130,11 @@ func (sc *SlotChain) RangeStatPrepareSlot(f func(slot StatPrepareSlot)) {
}
}

func (sc *SlotChain) AddStatPrepareSlotFirst(s StatPrepareSlot) {
ns := make([]StatPrepareSlot, 0, len(sc.statPres)+1)
// add to first
ns = append(ns, s)
sc.statPres = append(ns, sc.statPres...)
}

func (sc *SlotChain) AddStatPrepareSlotLast(s StatPrepareSlot) {
func (sc *SlotChain) AddStatPrepareSlot(s StatPrepareSlot) {
sc.statPres = append(sc.statPres, s)
sort.Slice(sc.statPres, func(i, j int) bool {
return sc.statPres[i].Order() < sc.statPres[j].Order()
})
}

// ValidateRuleCheckSlotNaming checks whether the name of RuleCheckSlot exists in SlotChain.[]RuleCheckSlot
Expand All @@ -157,14 +158,11 @@ func (sc *SlotChain) RangeRuleCheckSlot(f func(slot RuleCheckSlot)) {
}
}

func (sc *SlotChain) AddRuleCheckSlotFirst(s RuleCheckSlot) {
ns := make([]RuleCheckSlot, 0, len(sc.ruleChecks)+1)
ns = append(ns, s)
sc.ruleChecks = append(ns, sc.ruleChecks...)
}

func (sc *SlotChain) AddRuleCheckSlotLast(s RuleCheckSlot) {
func (sc *SlotChain) AddRuleCheckSlot(s RuleCheckSlot) {
sc.ruleChecks = append(sc.ruleChecks, s)
sort.Slice(sc.ruleChecks, func(i, j int) bool {
louyuting marked this conversation as resolved.
Show resolved Hide resolved
return sc.ruleChecks[i].Order() < sc.ruleChecks[j].Order()
})
}

// ValidateStatSlotNaming checks whether the name of StatSlot exists in SlotChain.[]StatSlot
Expand All @@ -188,14 +186,11 @@ func (sc *SlotChain) RangeStatSlot(f func(slot StatSlot)) {
}
}

func (sc *SlotChain) AddStatSlotFirst(s StatSlot) {
ns := make([]StatSlot, 0, len(sc.stats)+1)
ns = append(ns, s)
sc.stats = append(ns, sc.stats...)
}

func (sc *SlotChain) AddStatSlotLast(s StatSlot) {
func (sc *SlotChain) AddStatSlot(s StatSlot) {
sc.stats = append(sc.stats, s)
sort.Slice(sc.stats, func(i, j int) bool {
return sc.stats[i].Order() < sc.stats[j].Order()
})
}

// The entrance of slot chain
Expand Down
Loading