github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/cloud/circuitbreaker/circuitbreaker.go (about)

     1  // Copyright 2021 ByteDance Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package circuitbreaker
    16  
    17  import "time"
    18  
    19  // State changes between Closed, Open, HalfOpen
    20  // [Closed] -->- tripped ----> [Open]<-------+
    21  //    ^                          |           ^
    22  //    |                          v           |
    23  //    +                          |      detect fail
    24  //    |                          |           |
    25  //    |                    cooling timeout   |
    26  //    ^                          |           ^
    27  //    |                          v           |
    28  //    +--- detect succeed --<-[HalfOpen]-->--+
    29  //
    30  // The behaviors of each states:
    31  // =================================================================================================
    32  // |           | [Succeed]                  | [Fail or Timeout]       | [IsAllowed]                |
    33  // |================================================================================================
    34  // | [Closed]  | do nothing                 | if tripped, become Open | allow                      |
    35  // |================================================================================================
    36  // | [Open]    | do nothing                 | do nothing              | if cooling timeout, allow; |
    37  // |           |                            |                         | else reject                |
    38  // |================================================================================================
    39  // |           |increase halfopenSuccess,   |                         | if detect timeout, allow;  |
    40  // |[HalfOpen] |if(halfopenSuccess >=       | become Open             | else reject                |
    41  // |           | defaultHalfOpenSuccesses)|                         |                            |
    42  // |           |     become Closed          |                         |                            |
    43  // =================================================================================================
    44  type State int32
    45  
    46  func (s State) String() string {
    47  	switch s {
    48  	case Open:
    49  		return "OPEN"
    50  	case HalfOpen:
    51  		return "HALFOPEN"
    52  	case Closed:
    53  		return "CLOSED"
    54  	}
    55  	return "INVALID"
    56  }
    57  
    58  // represents the state
    59  const (
    60  	Open     State = iota
    61  	HalfOpen State = iota
    62  	Closed   State = iota
    63  )
    64  
    65  // BreakerStateChangeHandler .
    66  type BreakerStateChangeHandler func(oldState, newState State, m Metricer)
    67  
    68  // PanelStateChangeHandler .
    69  type PanelStateChangeHandler func(key string, oldState, newState State, m Metricer)
    70  
    71  // Options for breaker
    72  type Options struct {
    73  	// parameters for metricser
    74  	BucketTime time.Duration // the time each bucket holds
    75  	BucketNums int32         // the number of buckets the breaker have
    76  
    77  	// parameters for breaker
    78  	CoolingTimeout    time.Duration // fixed when create
    79  	DetectTimeout     time.Duration // fixed when create
    80  	HalfOpenSuccesses int32         // halfopen success is the threshold when the breaker is in HalfOpen;
    81  	// after exceeding consecutively this times, it will change its State from HalfOpen to Closed;
    82  
    83  	ShouldTrip                TripFunc                  // can be nil
    84  	ShouldTripWithKey         TripFuncWithKey           // can be nil, overwrites ShouldTrip
    85  	BreakerStateChangeHandler BreakerStateChangeHandler // can be nil
    86  
    87  	// if to use Per-P Metricer
    88  	// use Per-P Metricer can increase performance in multi-P condition
    89  	// but will consume more memory
    90  	EnableShardP bool
    91  
    92  	// Default value is time.Now, caller may use some high-performance custom time now func here
    93  	Now func() time.Time
    94  }
    95  
    96  const (
    97  	// bucket time is the time each bucket holds
    98  	defaultBucketTime = time.Millisecond * 100
    99  
   100  	// bucket nums is the number of buckets the metricser has;
   101  	// the more buckets you have, the less counters you lose when
   102  	// the oldest bucket expire;
   103  	defaultBucketNums = 100
   104  
   105  	// default window size is (defaultBucketTime * defaultBucketNums),
   106  	// which is 10 seconds;
   107  )