From f9ddf58e3a00ab1d6af781961c2503b6feaa4e55 Mon Sep 17 00:00:00 2001 From: louyuting Date: Wed, 9 Sep 2020 14:38:01 +0800 Subject: [PATCH] Add doc.go for core/api, flow and circuitbreaker package (#235) --- api/api.go | 1 - api/doc.go | 50 ++++++++++++++++ core/circuitbreaker/doc.go | 113 +++++++++++++++++++++++++++++++++++++ core/flow/doc.go | 16 ++++++ 4 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 api/doc.go create mode 100644 core/circuitbreaker/doc.go create mode 100644 core/flow/doc.go diff --git a/api/api.go b/api/api.go index 569deb35c..55c8f2fae 100644 --- a/api/api.go +++ b/api/api.go @@ -1,4 +1,3 @@ -// Package api provides fundamental APIs of Sentinel. package api import ( diff --git a/api/doc.go b/api/doc.go new file mode 100644 index 000000000..94670e9c8 --- /dev/null +++ b/api/doc.go @@ -0,0 +1,50 @@ +// Package api provides the topmost fundamental APIs for users using sentinel-golang. +// Users must initialize Sentinel before loading Sentinel rules. Sentinel support three ways to perform initialization: +// +// 1. api.InitDefault(), using default config to initialize. +// 2. api.InitWithConfig(confEntity *config.Entity), using customized config Entity to initialize. +// 3. api.InitWithConfigFile(configPath string), using yaml file to initialize. +// +// Here is the example code to use Sentinel: +// +// import sentinel "github.com/alibaba/sentinel-golang/api" +// +// err := sentinel.InitDefault() +// if err != nil { +// log.Fatal(err) +// } +// +// //Load sentinel rules +// _, err = flow.LoadRules([]*flow.Rule{ +// { +// Resource: "some-test", +// MetricType: flow.QPS, +// Count: 10, +// ControlBehavior: flow.Reject, +// }, +// }) +// if err != nil { +// log.Fatalf("Unexpected error: %+v", err) +// return +// } +// ch := make(chan struct{}) +// for i := 0; i < 10; i++ { +// go func() { +// for { +// e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound)) +// if b != nil { +// // Blocked. We could get the block reason from the BlockError. +// time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond) +// } else { +// // Passed, wrap the logic here. +// fmt.Println(util.CurrentTimeMillis(), "passed") +// time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond) +// // Be sure the entry is exited finally. +// e.Exit() +// } +// } +// }() +// } +// <-ch +// +package api diff --git a/core/circuitbreaker/doc.go b/core/circuitbreaker/doc.go new file mode 100644 index 000000000..a8e97a603 --- /dev/null +++ b/core/circuitbreaker/doc.go @@ -0,0 +1,113 @@ +// Package circuitbreaker implements the circuit breaker. +// +// Sentinel circuit breaker module converts each Rule into a CircuitBreaker. Each CircuitBreaker has its own statistical structure. +// +// Sentinel circuit breaker module supports three strategies: +// +// 1. SlowRequestRatio: the ratio of slow response time entry(entry's response time is great than max slow response time) exceeds the threshold. The following entry to resource will be broken. +// In SlowRequestRatio strategy, user must set max response time. +// 2. ErrorRatio: the ratio of error entry exceeds the threshold. The following entry to resource will be broken. +// 3. ErrorCount: the number of error entry exceeds the threshold. The following entry to resource will be broken. +// +// Sentinel circuit breaker is implemented based on state machines. There are three state: +// +// 1. Closed: all entries could pass checking. +// 2. Open: the circuit breaker is broken, all entries are blocked. After retry timeout, circuit breaker switches state to Half-Open and allows one entry to probe whether the resource returns to its expected state. +// 3. Half-Open: the circuit breaker is in a temporary state of probing, only one entry is allowed to access resource, others are blocked. +// +// Sentinel circuit breaker provides the listener to listen on the state changes. +// +// type StateChangeListener interface { +// OnTransformToClosed(prev State, rule Rule) +// +// OnTransformToOpen(prev State, rule Rule, snapshot interface{}) +// +// OnTransformToHalfOpen(prev State, rule Rule) +// } +// +// Here is the example code to use circuit breaker: +// +// type stateChangeTestListener struct {} +// +// func (s *stateChangeTestListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) { +// fmt.Printf("rule.steategy: %+v, From %s to Closed, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis()) +// } +// +// func (s *stateChangeTestListener) OnTransformToOpen(prev circuitbreaker.State, rule circuitbreaker.Rule, snapshot interface{}) { +// fmt.Printf("rule.steategy: %+v, From %s to Open, snapshot: %.2f, time: %d\n", rule.Strategy, prev.String(), snapshot, util.CurrentTimeMillis()) +// } +// +// func (s *stateChangeTestListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) { +// fmt.Printf("rule.steategy: %+v, From %s to Half-Open, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis()) +// } +// +// func main() { +// err := sentinel.InitDefault() +// if err != nil { +// log.Fatal(err) +// } +// ch := make(chan struct{}) +// // Register a state change listener so that we could observer the state change of the internal circuit breaker. +// circuitbreaker.RegisterStateChangeListeners(&stateChangeTestListener{}) +// +// _, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{ +// // Statistic time span=10s, recoveryTimeout=3s, slowRtUpperBound=50ms, maxSlowRequestRatio=50% +// { +// Resource: "abc", +// Strategy: circuitbreaker.SlowRequestRatio, +// RetryTimeoutMs: 3000, +// MinRequestAmount: 10, +// StatIntervalMs: 10000, +// MaxAllowedRtMs: 50, +// Threshold: 0.5, +// }, +// // Statistic time span=10s, recoveryTimeout=3s, maxErrorRatio=50% +// { +// Resource: "abc", +// Strategy: circuitbreaker.ErrorRatio, +// RetryTimeoutMs: 3000, +// MinRequestAmount: 10, +// StatIntervalMs: 10000, +// Threshold: 0.5, +// }, +// }) +// if err != nil { +// log.Fatal(err) +// } +// +// fmt.Println("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.") +// go func() { +// for { +// e, b := sentinel.Entry("abc") +// if b != nil { +// //fmt.Println("g1blocked") +// time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond) +// } else { +// if rand.Uint64()%20 > 9 { +// // Record current invocation as error. +// sentinel.TraceError(e, errors.New("biz error")) +// } +// //fmt.Println("g1passed") +// time.Sleep(time.Duration(rand.Uint64()%80+10) * time.Millisecond) +// e.Exit() +// } +// } +// }() +// +// go func() { +// for { +// e, b := sentinel.Entry("abc") +// if b != nil { +// //fmt.Println("g2blocked") +// time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond) +// } else { +// //fmt.Println("g2passed") +// time.Sleep(time.Duration(rand.Uint64()%80) * time.Millisecond) +// e.Exit() +// } +// } +// }() +// <-ch +// } +// +package circuitbreaker diff --git a/core/flow/doc.go b/core/flow/doc.go new file mode 100644 index 000000000..4a9968dd6 --- /dev/null +++ b/core/flow/doc.go @@ -0,0 +1,16 @@ +// Package flow implements the flow shaping control. +// +// flow module supports two statistic metric: QPS and Concurrency. +// +// The TrafficShapingController consists of two part: TrafficShapingCalculator and TrafficShapingChecker +// +// 1. TrafficShapingCalculator calculates the actual traffic shaping token threshold. Currently, Sentinel supports two token calculate strategy: Direct and WarmUp. +// 2. TrafficShapingChecker performs checking logic according to current metrics and the traffic shaping strategy, then yield the token result. Currently, Sentinel supports two control behavior: Reject and Throttling. +// +// Besides, Sentinel supports customized TrafficShapingCalculator and TrafficShapingChecker. User could call function SetTrafficShapingGenerator to register customized TrafficShapingController and call function RemoveTrafficShapingGenerator to unregister TrafficShapingController. +// There are a few notes users need to be aware of: +// +// 1. The function both SetTrafficShapingGenerator and RemoveTrafficShapingGenerator is not thread safe. +// 2. Users can not override the Sentinel supported TrafficShapingController. +// +package flow