diff --git a/core/breaker/breaker.go b/core/breaker/breaker.go index 9fc4a483..3da681cd 100644 --- a/core/breaker/breaker.go +++ b/core/breaker/breaker.go @@ -53,16 +53,19 @@ type ( // DoWithFallback runs the fallback if the Breaker rejects the request. // If a panic occurs in the request, the Breaker handles it as an error // and causes the same panic again. - DoWithFallback(req func() error, fallback func(err error) error) error + DoWithFallback(req func() error, fallback Fallback) error // DoWithFallbackAcceptable runs the given request if the Breaker accepts it. // DoWithFallbackAcceptable runs the fallback if the Breaker rejects the request. // If a panic occurs in the request, the Breaker handles it as an error // and causes the same panic again. // acceptable checks if it's a successful call, even if the error is not nil. - DoWithFallbackAcceptable(req func() error, fallback func(err error) error, acceptable Acceptable) error + DoWithFallbackAcceptable(req func() error, fallback Fallback, acceptable Acceptable) error } + // Fallback is the func to be called if the request is rejected. + Fallback func(err error) error + // Option defines the method to customize a Breaker. Option func(breaker *circuitBreaker) @@ -86,12 +89,12 @@ type ( internalThrottle interface { allow() (internalPromise, error) - doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error + doReq(req func() error, fallback Fallback, acceptable Acceptable) error } throttle interface { allow() (Promise, error) - doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error + doReq(req func() error, fallback Fallback, acceptable Acceptable) error } ) @@ -122,11 +125,11 @@ func (cb *circuitBreaker) DoWithAcceptable(req func() error, acceptable Acceptab return cb.throttle.doReq(req, nil, acceptable) } -func (cb *circuitBreaker) DoWithFallback(req func() error, fallback func(err error) error) error { +func (cb *circuitBreaker) DoWithFallback(req func() error, fallback Fallback) error { return cb.throttle.doReq(req, fallback, defaultAcceptable) } -func (cb *circuitBreaker) DoWithFallbackAcceptable(req func() error, fallback func(err error) error, +func (cb *circuitBreaker) DoWithFallbackAcceptable(req func() error, fallback Fallback, acceptable Acceptable) error { return cb.throttle.doReq(req, fallback, acceptable) } @@ -168,7 +171,7 @@ func (lt loggedThrottle) allow() (Promise, error) { }, lt.logError(err) } -func (lt loggedThrottle) doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error { +func (lt loggedThrottle) doReq(req func() error, fallback Fallback, acceptable Acceptable) error { return lt.logError(lt.internalThrottle.doReq(req, fallback, func(err error) bool { accept := acceptable(err) if !accept && err != nil { diff --git a/core/breaker/breakers.go b/core/breaker/breakers.go index be55d55a..314965c4 100644 --- a/core/breaker/breakers.go +++ b/core/breaker/breakers.go @@ -22,14 +22,14 @@ func DoWithAcceptable(name string, req func() error, acceptable Acceptable) erro } // DoWithFallback calls Breaker.DoWithFallback on the Breaker with given name. -func DoWithFallback(name string, req func() error, fallback func(err error) error) error { +func DoWithFallback(name string, req func() error, fallback Fallback) error { return do(name, func(b Breaker) error { return b.DoWithFallback(req, fallback) }) } // DoWithFallbackAcceptable calls Breaker.DoWithFallbackAcceptable on the Breaker with given name. -func DoWithFallbackAcceptable(name string, req func() error, fallback func(err error) error, +func DoWithFallbackAcceptable(name string, req func() error, fallback Fallback, acceptable Acceptable) error { return do(name, func(b Breaker) error { return b.DoWithFallbackAcceptable(req, fallback, acceptable) diff --git a/core/breaker/googlebreaker.go b/core/breaker/googlebreaker.go index a8432e30..f58566b0 100644 --- a/core/breaker/googlebreaker.go +++ b/core/breaker/googlebreaker.go @@ -1,7 +1,6 @@ package breaker import ( - "math" "time" "github.com/zeromicro/go-zero/core/collection" @@ -38,7 +37,8 @@ func (b *googleBreaker) accept() error { accepts, total := b.history() weightedAccepts := b.k * float64(accepts) // https://landing.google.com/sre/sre-book/chapters/handling-overload/#eq2101 - dropRatio := math.Max(0, (float64(total-protection)-weightedAccepts)/float64(total+1)) + // for better performance, no need to care about negative ratio + dropRatio := (float64(total-protection) - weightedAccepts) / float64(total+1) if dropRatio <= 0 { return nil } @@ -60,8 +60,9 @@ func (b *googleBreaker) allow() (internalPromise, error) { }, nil } -func (b *googleBreaker) doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error { +func (b *googleBreaker) doReq(req func() error, fallback Fallback, acceptable Acceptable) error { if err := b.accept(); err != nil { + b.markFailure() if fallback != nil { return fallback(err) } @@ -69,18 +70,19 @@ func (b *googleBreaker) doReq(req func() error, fallback func(err error) error, return err } + var success bool defer func() { - if e := recover(); e != nil { + // if req() panic, success is false, mark as failure + if success { + b.markSuccess() + } else { b.markFailure() - panic(e) } }() err := req() if acceptable(err) { - b.markSuccess() - } else { - b.markFailure() + success = true } return err diff --git a/core/breaker/googlebreaker_test.go b/core/breaker/googlebreaker_test.go index 7a8c65b8..85d76660 100644 --- a/core/breaker/googlebreaker_test.go +++ b/core/breaker/googlebreaker_test.go @@ -206,7 +206,7 @@ func BenchmarkGoogleBreakerAllow(b *testing.B) { breaker := getGoogleBreaker() b.ResetTimer() for i := 0; i <= b.N; i++ { - breaker.accept() + _ = breaker.accept() if i%2 == 0 { breaker.markSuccess() } else { @@ -215,6 +215,16 @@ func BenchmarkGoogleBreakerAllow(b *testing.B) { } } +func BenchmarkGoogleBreakerDoReq(b *testing.B) { + breaker := getGoogleBreaker() + b.ResetTimer() + for i := 0; i <= b.N; i++ { + _ = breaker.doReq(func() error { + return nil + }, nil, defaultAcceptable) + } +} + func markSuccess(b *googleBreaker, count int) { for i := 0; i < count; i++ { p, err := b.allow() diff --git a/core/breaker/nopbreaker.go b/core/breaker/nopbreaker.go index a1b2e7cc..cd030b63 100644 --- a/core/breaker/nopbreaker.go +++ b/core/breaker/nopbreaker.go @@ -24,12 +24,11 @@ func (b nopBreaker) DoWithAcceptable(req func() error, _ Acceptable) error { return req() } -func (b nopBreaker) DoWithFallback(req func() error, _ func(err error) error) error { +func (b nopBreaker) DoWithFallback(req func() error, _ Fallback) error { return req() } -func (b nopBreaker) DoWithFallbackAcceptable(req func() error, _ func(err error) error, - _ Acceptable) error { +func (b nopBreaker) DoWithFallbackAcceptable(req func() error, _ Fallback, _ Acceptable) error { return req() } diff --git a/core/conf/readme.md b/core/conf/readme.md index 7bd58540..c34a3b67 100644 --- a/core/conf/readme.md +++ b/core/conf/readme.md @@ -12,7 +12,7 @@ type RestfulConf struct { MaxConns int `json:",default=10000"` MaxBytes int64 `json:",default=1048576"` Timeout time.Duration `json:",default=3s"` - CpuThreshold int64 `json:",default=900,range=[0:1000]"` + CpuThreshold int64 `json:",default=900,range=[0:1000)"` } ``` diff --git a/core/load/adaptiveshedder.go b/core/load/adaptiveshedder.go index 4d1b7f1d..a7b6f49d 100644 --- a/core/load/adaptiveshedder.go +++ b/core/load/adaptiveshedder.go @@ -9,6 +9,7 @@ import ( "github.com/zeromicro/go-zero/core/collection" "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/mathx" "github.com/zeromicro/go-zero/core/stat" "github.com/zeromicro/go-zero/core/syncx" "github.com/zeromicro/go-zero/core/timex" @@ -21,8 +22,11 @@ const ( defaultCpuThreshold = 900 defaultMinRt = float64(time.Second / time.Millisecond) // moving average hyperparameter beta for calculating requests on the fly - flyingBeta = 0.9 - coolOffDuration = time.Second + flyingBeta = 0.9 + coolOffDuration = time.Second + cpuMax = 1000 // millicpu + millisecondsPerSecond = 1000 + overloadFactorLowerBound = 0.1 ) var ( @@ -66,7 +70,7 @@ type ( adaptiveShedder struct { cpuThreshold int64 - windows int64 + windowScale float64 flying int64 avgFlying float64 avgFlyingLock syncx.SpinLock @@ -105,7 +109,7 @@ func NewAdaptiveShedder(opts ...ShedderOption) Shedder { bucketDuration := options.window / time.Duration(options.buckets) return &adaptiveShedder{ cpuThreshold: options.cpuThreshold, - windows: int64(time.Second / bucketDuration), + windowScale: float64(time.Second) / float64(bucketDuration) / millisecondsPerSecond, overloadTime: syncx.NewAtomicDuration(), droppedRecently: syncx.NewAtomicBool(), passCounter: collection.NewRollingWindow(options.buckets, bucketDuration, @@ -149,16 +153,17 @@ func (as *adaptiveShedder) highThru() bool { as.avgFlyingLock.Lock() avgFlying := as.avgFlying as.avgFlyingLock.Unlock() - maxFlight := as.maxFlight() - return int64(avgFlying) > maxFlight && atomic.LoadInt64(&as.flying) > maxFlight + maxFlight := as.maxFlight() * as.overloadFactor() + return avgFlying > maxFlight && float64(atomic.LoadInt64(&as.flying)) > maxFlight } -func (as *adaptiveShedder) maxFlight() int64 { +func (as *adaptiveShedder) maxFlight() float64 { // windows = buckets per second // maxQPS = maxPASS * windows // minRT = min average response time in milliseconds - // maxQPS * minRT / milliseconds_per_second - return int64(math.Max(1, float64(as.maxPass()*as.windows)*(as.minRt()/1e3))) + // allowedFlying = maxQPS * minRT / milliseconds_per_second + maxFlight := float64(as.maxPass()) * as.minRt() * as.windowScale + return mathx.AtLeast(maxFlight, 1) } func (as *adaptiveShedder) maxPass() int64 { @@ -174,6 +179,8 @@ func (as *adaptiveShedder) maxPass() int64 { } func (as *adaptiveShedder) minRt() float64 { + // if no requests in previous windows, return defaultMinRt, + // its a reasonable large value to avoid dropping requests. result := defaultMinRt as.rtCounter.Reduce(func(b *collection.Bucket) { @@ -190,6 +197,13 @@ func (as *adaptiveShedder) minRt() float64 { return result } +func (as *adaptiveShedder) overloadFactor() float64 { + // as.cpuThreshold must be less than cpuMax + factor := (cpuMax - float64(stat.CpuUsage())) / (cpuMax - float64(as.cpuThreshold)) + // at least accept 10% of acceptable requests even cpu is highly overloaded. + return mathx.Between(factor, overloadFactorLowerBound, 1) +} + func (as *adaptiveShedder) shouldDrop() bool { if as.systemOverloaded() || as.stillHot() { if as.highThru() { diff --git a/core/load/adaptiveshedder_test.go b/core/load/adaptiveshedder_test.go index 94789322..104be20e 100644 --- a/core/load/adaptiveshedder_test.go +++ b/core/load/adaptiveshedder_test.go @@ -19,6 +19,7 @@ import ( const ( buckets = 10 bucketDuration = time.Millisecond * 50 + windowFactor = 0.01 ) func init() { @@ -114,10 +115,10 @@ func TestAdaptiveShedderMaxFlight(t *testing.T) { shedder := &adaptiveShedder{ passCounter: passCounter, rtCounter: rtCounter, - windows: buckets, + windowScale: windowFactor, droppedRecently: syncx.NewAtomicBool(), } - assert.Equal(t, int64(54), shedder.maxFlight()) + assert.Equal(t, float64(54), shedder.maxFlight()) } func TestAdaptiveShedderShouldDrop(t *testing.T) { @@ -136,7 +137,7 @@ func TestAdaptiveShedderShouldDrop(t *testing.T) { shedder := &adaptiveShedder{ passCounter: passCounter, rtCounter: rtCounter, - windows: buckets, + windowScale: windowFactor, overloadTime: syncx.NewAtomicDuration(), droppedRecently: syncx.NewAtomicBool(), } @@ -149,7 +150,8 @@ func TestAdaptiveShedderShouldDrop(t *testing.T) { // cpu >= 800, inflight > maxPass shedder.avgFlying = 80 - shedder.flying = 50 + // because of the overloadFactor, so we need to make sure maxFlight is greater than flying + shedder.flying = int64(shedder.maxFlight()*shedder.overloadFactor()) - 5 assert.False(t, shedder.shouldDrop()) // cpu >= 800, inflight > maxPass @@ -190,7 +192,7 @@ func TestAdaptiveShedderStillHot(t *testing.T) { shedder := &adaptiveShedder{ passCounter: passCounter, rtCounter: rtCounter, - windows: buckets, + windowScale: windowFactor, overloadTime: syncx.NewAtomicDuration(), droppedRecently: syncx.ForAtomicBool(true), } @@ -239,6 +241,30 @@ func BenchmarkAdaptiveShedder_Allow(b *testing.B) { b.Run("low load", bench) } +func BenchmarkMaxFlight(b *testing.B) { + passCounter := newRollingWindow() + rtCounter := newRollingWindow() + for i := 0; i < 10; i++ { + if i > 0 { + time.Sleep(bucketDuration) + } + passCounter.Add(float64((i + 1) * 100)) + for j := i*10 + 1; j <= i*10+10; j++ { + rtCounter.Add(float64(j)) + } + } + shedder := &adaptiveShedder{ + passCounter: passCounter, + rtCounter: rtCounter, + windowScale: windowFactor, + droppedRecently: syncx.NewAtomicBool(), + } + + for i := 0; i < b.N; i++ { + _ = shedder.maxFlight() + } +} + func newRollingWindow() *collection.RollingWindow { return collection.NewRollingWindow(buckets, bucketDuration, collection.IgnoreCurrentBucket()) } diff --git a/core/logx/logs.go b/core/logx/logs.go index 817cb557..0c049324 100644 --- a/core/logx/logs.go +++ b/core/logx/logs.go @@ -17,14 +17,13 @@ import ( const callerDepth = 4 var ( - timeFormat = "2006-01-02T15:04:05.000Z07:00" - logLevel uint32 + timeFormat = "2006-01-02T15:04:05.000Z07:00" encoding uint32 = jsonEncodingType // maxContentLength is used to truncate the log content, 0 for not truncating. maxContentLength uint32 // use uint32 for atomic operations - disableLog uint32 disableStat uint32 + logLevel uint32 options logOptions writer = new(atomicWriter) setupOnce sync.Once @@ -96,7 +95,7 @@ func Debugw(msg string, fields ...LogField) { // Disable disables the logging. func Disable() { - atomic.StoreUint32(&disableLog, 1) + atomic.StoreUint32(&logLevel, disableLevel) writer.Store(nopWriter{}) } @@ -250,7 +249,7 @@ func SetLevel(level uint32) { // SetWriter sets the logging writer. It can be used to customize the logging. func SetWriter(w Writer) { - if atomic.LoadUint32(&disableLog) == 0 { + if atomic.LoadUint32(&logLevel) != disableLevel { writer.Store(w) } } diff --git a/core/logx/logs_test.go b/core/logx/logs_test.go index 0b37960f..818f459e 100644 --- a/core/logx/logs_test.go +++ b/core/logx/logs_test.go @@ -666,6 +666,7 @@ func TestDisable(t *testing.T) { WithMaxSize(1024)(&opt) assert.Nil(t, Close()) assert.Nil(t, Close()) + assert.Equal(t, uint32(disableLevel), atomic.LoadUint32(&logLevel)) } func TestDisableStat(t *testing.T) { @@ -680,7 +681,7 @@ func TestDisableStat(t *testing.T) { } func TestSetWriter(t *testing.T) { - atomic.StoreUint32(&disableLog, 0) + atomic.StoreUint32(&logLevel, 0) Reset() SetWriter(nopWriter{}) assert.NotNil(t, writer.Load()) diff --git a/core/logx/vars.go b/core/logx/vars.go index 59688e87..90ef3628 100644 --- a/core/logx/vars.go +++ b/core/logx/vars.go @@ -15,6 +15,8 @@ const ( ErrorLevel // SevereLevel only log severe messages SevereLevel + // disableLevel doesn't log any messages + disableLevel = 0xff ) const ( diff --git a/core/mathx/entropy_test.go b/core/mathx/entropy_test.go index 3b6c2659..03db018d 100644 --- a/core/mathx/entropy_test.go +++ b/core/mathx/entropy_test.go @@ -15,3 +15,17 @@ func TestCalcEntropy(t *testing.T) { } assert.True(t, CalcEntropy(m) > .99) } + +func TestCalcEmptyEntropy(t *testing.T) { + m := make(map[any]int) + assert.Equal(t, float64(1), CalcEntropy(m)) +} + +func TestCalcDiffEntropy(t *testing.T) { + const total = 1000 + m := make(map[any]int, total) + for i := 0; i < total; i++ { + m[i] = i + } + assert.True(t, CalcEntropy(m) < .99) +} diff --git a/core/mathx/range.go b/core/mathx/range.go new file mode 100644 index 00000000..d74ac4dd --- /dev/null +++ b/core/mathx/range.go @@ -0,0 +1,34 @@ +package mathx + +type numerical interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | + ~float32 | ~float64 +} + +// AtLeast returns the greater of x or lower. +func AtLeast[T numerical](x, lower T) T { + if x < lower { + return lower + } + return x +} + +// AtMost returns the smaller of x or upper. +func AtMost[T numerical](x, upper T) T { + if x > upper { + return upper + } + return x +} + +// Between returns the value of x clamped to the range [lower, upper]. +func Between[T numerical](x, lower, upper T) T { + if x < lower { + return lower + } + if x > upper { + return upper + } + return x +} diff --git a/core/mathx/range_test.go b/core/mathx/range_test.go new file mode 100644 index 00000000..bff9c2bc --- /dev/null +++ b/core/mathx/range_test.go @@ -0,0 +1,513 @@ +package mathx + +import "testing" + +func TestAtLeast(t *testing.T) { + t.Run("test int", func(t *testing.T) { + if got := AtLeast(10, 5); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(3, 5); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(5, 5); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test int8", func(t *testing.T) { + if got := AtLeast(int8(10), int8(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(int8(3), int8(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(int8(5), int8(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test int16", func(t *testing.T) { + if got := AtLeast(int16(10), int16(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(int16(3), int16(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(int16(5), int16(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test int32", func(t *testing.T) { + if got := AtLeast(int32(10), int32(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(int32(3), int32(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(int32(5), int32(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test int64", func(t *testing.T) { + if got := AtLeast(int64(10), int64(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(int64(3), int64(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(int64(5), int64(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test uint", func(t *testing.T) { + if got := AtLeast(uint(10), uint(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(uint(3), uint(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(uint(5), uint(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test uint8", func(t *testing.T) { + if got := AtLeast(uint8(10), uint8(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(uint8(3), uint8(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(uint8(5), uint8(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test uint16", func(t *testing.T) { + if got := AtLeast(uint16(10), uint16(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(uint16(3), uint16(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(uint16(5), uint16(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test uint32", func(t *testing.T) { + if got := AtLeast(uint32(10), uint32(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(uint32(3), uint32(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(uint32(5), uint32(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test uint64", func(t *testing.T) { + if got := AtLeast(uint64(10), uint64(5)); got != 10 { + t.Errorf("AtLeast() = %v, want 10", got) + } + if got := AtLeast(uint64(3), uint64(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + if got := AtLeast(uint64(5), uint64(5)); got != 5 { + t.Errorf("AtLeast() = %v, want 5", got) + } + }) + + t.Run("test float32", func(t *testing.T) { + if got := AtLeast(float32(10.0), float32(5.0)); got != 10.0 { + t.Errorf("AtLeast() = %v, want 10.0", got) + } + if got := AtLeast(float32(3.0), float32(5.0)); got != 5.0 { + t.Errorf("AtLeast() = %v, want 5.0", got) + } + if got := AtLeast(float32(5.0), float32(5.0)); got != 5.0 { + t.Errorf("AtLeast() = %v, want 5.0", got) + } + }) + + t.Run("test float64", func(t *testing.T) { + if got := AtLeast(10.0, 5.0); got != 10.0 { + t.Errorf("AtLeast() = %v, want 10.0", got) + } + if got := AtLeast(3.0, 5.0); got != 5.0 { + t.Errorf("AtLeast() = %v, want 5.0", got) + } + if got := AtLeast(5.0, 5.0); got != 5.0 { + t.Errorf("AtLeast() = %v, want 5.0", got) + } + }) +} + +func TestAtMost(t *testing.T) { + t.Run("test int", func(t *testing.T) { + if got := AtMost(10, 5); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(3, 5); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(5, 5); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test int8", func(t *testing.T) { + if got := AtMost(int8(10), int8(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(int8(3), int8(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(int8(5), int8(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test int16", func(t *testing.T) { + if got := AtMost(int16(10), int16(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(int16(3), int16(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(int16(5), int16(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test int32", func(t *testing.T) { + if got := AtMost(int32(10), int32(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(int32(3), int32(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(int32(5), int32(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test int64", func(t *testing.T) { + if got := AtMost(int64(10), int64(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(int64(3), int64(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(int64(5), int64(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test uint", func(t *testing.T) { + if got := AtMost(uint(10), uint(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(uint(3), uint(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(uint(5), uint(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test uint8", func(t *testing.T) { + if got := AtMost(uint8(10), uint8(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(uint8(3), uint8(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(uint8(5), uint8(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test uint16", func(t *testing.T) { + if got := AtMost(uint16(10), uint16(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(uint16(3), uint16(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(uint16(5), uint16(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test uint32", func(t *testing.T) { + if got := AtMost(uint32(10), uint32(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(uint32(3), uint32(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(uint32(5), uint32(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test uint64", func(t *testing.T) { + if got := AtMost(uint64(10), uint64(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + if got := AtMost(uint64(3), uint64(5)); got != 3 { + t.Errorf("AtMost() = %v, want 3", got) + } + if got := AtMost(uint64(5), uint64(5)); got != 5 { + t.Errorf("AtMost() = %v, want 5", got) + } + }) + + t.Run("test float32", func(t *testing.T) { + if got := AtMost(float32(10.0), float32(5.0)); got != 5.0 { + t.Errorf("AtMost() = %v, want 5.0", got) + } + if got := AtMost(float32(3.0), float32(5.0)); got != 3.0 { + t.Errorf("AtMost() = %v, want 3.0", got) + } + if got := AtMost(float32(5.0), float32(5.0)); got != 5.0 { + t.Errorf("AtMost() = %v, want 5.0", got) + } + }) + + t.Run("test float64", func(t *testing.T) { + if got := AtMost(10.0, 5.0); got != 5.0 { + t.Errorf("AtMost() = %v, want 5.0", got) + } + if got := AtMost(3.0, 5.0); got != 3.0 { + t.Errorf("AtMost() = %v, want 3.0", got) + } + if got := AtMost(5.0, 5.0); got != 5.0 { + t.Errorf("AtMost() = %v, want 5.0", got) + } + }) +} + +func TestBetween(t *testing.T) { + t.Run("test int", func(t *testing.T) { + if got := Between(10, 5, 15); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(3, 5, 15); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(20, 5, 15); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(5, 5, 15); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(15, 5, 15); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test int8", func(t *testing.T) { + if got := Between(int8(10), int8(5), int8(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(int8(3), int8(5), int8(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int8(20), int8(5), int8(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(int8(5), int8(5), int8(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int8(15), int8(5), int8(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test int16", func(t *testing.T) { + if got := Between(int16(10), int16(5), int16(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(int16(3), int16(5), int16(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int16(20), int16(5), int16(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(int16(5), int16(5), int16(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int16(15), int16(5), int16(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test int32", func(t *testing.T) { + if got := Between(int32(10), int32(5), int32(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(int32(3), int32(5), int32(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int32(20), int32(5), int32(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(int32(5), int32(5), int32(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int32(15), int32(5), int32(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test int64", func(t *testing.T) { + if got := Between(int64(10), int64(5), int64(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(int64(3), int64(5), int64(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int64(20), int64(5), int64(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(int64(5), int64(5), int64(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(int64(15), int64(5), int64(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test uint", func(t *testing.T) { + if got := Between(uint(10), uint(5), uint(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(uint(3), uint(5), uint(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint(20), uint(5), uint(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(uint(5), uint(5), uint(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint(15), uint(5), uint(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test uint8", func(t *testing.T) { + if got := Between(uint8(10), uint8(5), uint8(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(uint8(3), uint8(5), uint8(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint8(20), uint8(5), uint8(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(uint8(5), uint8(5), uint8(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint8(15), uint8(5), uint8(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test uint16", func(t *testing.T) { + if got := Between(uint16(10), uint16(5), uint16(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(uint16(3), uint16(5), uint16(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint16(20), uint16(5), uint16(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(uint16(5), uint16(5), uint16(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint16(15), uint16(5), uint16(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test uint32", func(t *testing.T) { + if got := Between(uint32(10), uint32(5), uint32(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(uint32(3), uint32(5), uint32(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint32(20), uint32(5), uint32(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(uint32(5), uint32(5), uint32(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint32(15), uint32(5), uint32(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test uint64", func(t *testing.T) { + if got := Between(uint64(10), uint64(5), uint64(15)); got != 10 { + t.Errorf("Between() = %v, want 10", got) + } + if got := Between(uint64(3), uint64(5), uint64(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint64(20), uint64(5), uint64(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + if got := Between(uint64(5), uint64(5), uint64(15)); got != 5 { + t.Errorf("Between() = %v, want 5", got) + } + if got := Between(uint64(15), uint64(5), uint64(15)); got != 15 { + t.Errorf("Between() = %v, want 15", got) + } + }) + + t.Run("test float32", func(t *testing.T) { + if got := Between(float32(10.0), float32(5.0), float32(15.0)); got != 10.0 { + t.Errorf("Between() = %v, want 10.0", got) + } + if got := Between(float32(3.0), float32(5.0), float32(15.0)); got != 5.0 { + t.Errorf("Between() = %v, want 5.0", got) + } + if got := Between(float32(20.0), float32(5.0), float32(15.0)); got != 15.0 { + t.Errorf("Between() = %v, want 15.0", got) + } + if got := Between(float32(5.0), float32(5.0), float32(15.0)); got != 5.0 { + t.Errorf("Between() = %v, want 5.0", got) + } + if got := Between(float32(15.0), float32(5.0), float32(15.0)); got != 15.0 { + t.Errorf("Between() = %v, want 15.0", got) + } + }) + + t.Run("test float64", func(t *testing.T) { + if got := Between(10.0, 5.0, 15.0); got != 10.0 { + t.Errorf("Between() = %v, want 10.0", got) + } + if got := Between(3.0, 5.0, 15.0); got != 5.0 { + t.Errorf("Between() = %v, want 5.0", got) + } + if got := Between(20.0, 5.0, 15.0); got != 15.0 { + t.Errorf("Between() = %v, want 15.0", got) + } + if got := Between(5.0, 5.0, 15.0); got != 5.0 { + t.Errorf("Between() = %v, want 5.0", got) + } + if got := Between(15.0, 5.0, 15.0); got != 15.0 { + t.Errorf("Between() = %v, want 15.0", got) + } + }) +} diff --git a/core/stat/internal/cgroup_linux_test.go b/core/stat/internal/cgroup_linux_test.go index 5b2eaeaa..a8a54678 100644 --- a/core/stat/internal/cgroup_linux_test.go +++ b/core/stat/internal/cgroup_linux_test.go @@ -12,27 +12,30 @@ func TestRunningInUserNS(t *testing.T) { assert.False(t, runningInUserNS()) } -func TestCgroupV1(t *testing.T) { - if isCgroup2UnifiedMode() { +func TestCgroups(t *testing.T) { + // test cgroup legacy(v1) & hybrid + if !isCgroup2UnifiedMode() { cg, err := currentCgroupV1() assert.NoError(t, err) _, err = cg.effectiveCpus() - assert.Error(t, err) + assert.NoError(t, err) _, err = cg.cpuQuota() - assert.Error(t, err) + assert.NoError(t, err) _, err = cg.cpuUsage() - assert.Error(t, err) + assert.NoError(t, err) } // test cgroup v2 - cg, err := currentCgroupV2() - assert.NoError(t, err) - _, err = cg.effectiveCpus() - assert.NoError(t, err) - _, err = cg.cpuQuota() - assert.Error(t, err) - _, err = cg.cpuUsage() - assert.NoError(t, err) + if isCgroup2UnifiedMode() { + cg, err := currentCgroupV2() + assert.NoError(t, err) + _, err = cg.effectiveCpus() + assert.NoError(t, err) + _, err = cg.cpuQuota() + assert.Error(t, err) + _, err = cg.cpuUsage() + assert.NoError(t, err) + } } func TestParseUint(t *testing.T) { diff --git a/core/stores/mon/collection_test.go b/core/stores/mon/collection_test.go index ac65bbd9..2adc27f0 100644 --- a/core/stores/mon/collection_test.go +++ b/core/stores/mon/collection_test.go @@ -603,11 +603,11 @@ func (d *dropBreaker) DoWithAcceptable(_ func() error, _ breaker.Acceptable) err return errDummy } -func (d *dropBreaker) DoWithFallback(_ func() error, _ func(err error) error) error { +func (d *dropBreaker) DoWithFallback(_ func() error, _ breaker.Fallback) error { return nil } -func (d *dropBreaker) DoWithFallbackAcceptable(_ func() error, _ func(err error) error, +func (d *dropBreaker) DoWithFallbackAcceptable(_ func() error, _ breaker.Fallback, _ breaker.Acceptable) error { return nil } diff --git a/core/threading/taskrunner.go b/core/threading/taskrunner.go index 955beeab..18ac4f6c 100644 --- a/core/threading/taskrunner.go +++ b/core/threading/taskrunner.go @@ -1,13 +1,20 @@ package threading import ( + "errors" + "sync" + "github.com/zeromicro/go-zero/core/lang" "github.com/zeromicro/go-zero/core/rescue" ) +// ErrTaskRunnerBusy is the error that indicates the runner is busy. +var ErrTaskRunnerBusy = errors.New("task runner is busy") + // A TaskRunner is used to control the concurrency of goroutines. type TaskRunner struct { limitChan chan lang.PlaceholderType + waitGroup sync.WaitGroup } // NewTaskRunner returns a TaskRunner. @@ -19,13 +26,47 @@ func NewTaskRunner(concurrency int) *TaskRunner { // Schedule schedules a task to run under concurrency control. func (rp *TaskRunner) Schedule(task func()) { + // Why we add waitGroup first, in case of race condition on starting a task and wait returns. + // For example, limitChan is full, and the task is scheduled to run, but the waitGroup is not added, + // then the wait returns, and the task is then scheduled to run, but caller thinks all tasks are done. + // the same reason for ScheduleImmediately. + rp.waitGroup.Add(1) rp.limitChan <- lang.Placeholder go func() { defer rescue.Recover(func() { <-rp.limitChan + rp.waitGroup.Done() }) task() }() } + +// ScheduleImmediately schedules a task to run immediately under concurrency control. +// It returns ErrTaskRunnerBusy if the runner is busy. +func (rp *TaskRunner) ScheduleImmediately(task func()) error { + // Why we add waitGroup first, check the comment in Schedule. + rp.waitGroup.Add(1) + select { + case rp.limitChan <- lang.Placeholder: + default: + rp.waitGroup.Done() + return ErrTaskRunnerBusy + } + + go func() { + defer rescue.Recover(func() { + <-rp.limitChan + rp.waitGroup.Done() + }) + task() + }() + + return nil +} + +// Wait waits all running tasks to be done. +func (rp *TaskRunner) Wait() { + rp.waitGroup.Wait() +} diff --git a/core/threading/taskrunner_test.go b/core/threading/taskrunner_test.go index 81cefc82..7771760a 100644 --- a/core/threading/taskrunner_test.go +++ b/core/threading/taskrunner_test.go @@ -2,32 +2,52 @@ package threading import ( "runtime" - "sync" "sync/atomic" "testing" + "time" "github.com/stretchr/testify/assert" ) -func TestRoutinePool(t *testing.T) { +func TestTaskRunner_Schedule(t *testing.T) { times := 100 pool := NewTaskRunner(runtime.NumCPU()) var counter int32 - var waitGroup sync.WaitGroup for i := 0; i < times; i++ { - waitGroup.Add(1) pool.Schedule(func() { atomic.AddInt32(&counter, 1) - waitGroup.Done() }) } - waitGroup.Wait() + pool.Wait() assert.Equal(t, times, int(counter)) } +func TestTaskRunner_ScheduleImmediately(t *testing.T) { + cpus := runtime.NumCPU() + times := cpus * 2 + pool := NewTaskRunner(cpus) + + var counter int32 + for i := 0; i < times; i++ { + err := pool.ScheduleImmediately(func() { + atomic.AddInt32(&counter, 1) + time.Sleep(time.Millisecond * 100) + }) + if i < cpus { + assert.Nil(t, err) + } else { + assert.ErrorIs(t, err, ErrTaskRunnerBusy) + } + } + + pool.Wait() + + assert.Equal(t, cpus, int(counter)) +} + func BenchmarkRoutinePool(b *testing.B) { queue := NewTaskRunner(runtime.NumCPU()) for i := 0; i < b.N; i++ { diff --git a/go.mod b/go.mod index 29ebe2a7..f138d94e 100644 --- a/go.mod +++ b/go.mod @@ -13,17 +13,17 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/google/uuid v1.5.0 - github.com/jackc/pgx/v5 v5.5.2 - github.com/jhump/protoreflect v1.15.4 + github.com/google/uuid v1.6.0 + github.com/jackc/pgx/v5 v5.5.3 + github.com/jhump/protoreflect v1.15.6 github.com/olekukonko/tablewriter v0.0.5 github.com/pelletier/go-toml/v2 v2.1.1 github.com/prometheus/client_golang v1.18.0 github.com/redis/go-redis/v9 v9.4.0 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.8.4 - go.etcd.io/etcd/api/v3 v3.5.11 - go.etcd.io/etcd/client/v3 v3.5.11 + go.etcd.io/etcd/api/v3 v3.5.12 + go.etcd.io/etcd/client/v3 v3.5.12 go.mongodb.org/mongo-driver v1.13.1 go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel/exporters/jaeger v1.17.0 @@ -35,25 +35,25 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 go.uber.org/automaxprocs v1.5.3 go.uber.org/goleak v1.2.1 - golang.org/x/net v0.20.0 - golang.org/x/sys v0.16.0 + golang.org/x/net v0.21.0 + golang.org/x/sys v0.17.0 golang.org/x/time v0.5.0 - google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b - google.golang.org/grpc v1.60.1 + google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 + google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 gopkg.in/cheggaaa/pb.v1 v1.0.28 gopkg.in/h2non/gock.v1 v1.1.2 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/client-go v0.29.0 + k8s.io/api v0.29.2 + k8s.io/apimachinery v0.29.2 + k8s.io/client-go v0.29.2 k8s.io/utils v0.0.0-20230726121419-3b25d923346b ) require ( github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bufbuild/protocompile v0.7.1 // indirect + github.com/bufbuild/protocompile v0.8.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -99,21 +99,21 @@ require ( github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yuin/gopher-lua v1.1.0 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.11 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/oauth2 v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect diff --git a/go.sum b/go.sum index 5737de8c..df825bbd 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bufbuild/protocompile v0.7.1 h1:Kd8fb6EshOHXNNRtYAmLAwy/PotlyFoN0iMbuwGNh0M= -github.com/bufbuild/protocompile v0.7.1/go.mod h1:+Etjg4guZoAqzVk2czwEQP12yaxLJ8DxuqCJ9qHdH94= +github.com/bufbuild/protocompile v0.8.0 h1:9Kp1q6OkS9L4nM3FYbr8vlJnEwtbpDPQlQOVXfR+78s= +github.com/bufbuild/protocompile v0.8.0/go.mod h1:+Etjg4guZoAqzVk2czwEQP12yaxLJ8DxuqCJ9qHdH94= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -84,8 +84,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= @@ -94,12 +94,12 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.2 h1:iLlpgp4Cp/gC9Xuscl7lFL1PhhW+ZLtXZcrfCt4C3tA= -github.com/jackc/pgx/v5 v5.5.2/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s= +github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jhump/protoreflect v1.15.4 h1:mrwJhfQGGljwvR/jPEocli8KA6G9afbQpH8NY2wORcI= -github.com/jhump/protoreflect v1.15.4/go.mod h1:2B+zwrnMY3TTIqEK01OG/d3pyUycQBfDf+bx8fE2DNg= +github.com/jhump/protoreflect v1.15.6 h1:WMYJbw2Wo+KOWwZFvgY0jMoVHM6i4XIvRs2RcBj5VmI= +github.com/jhump/protoreflect v1.15.6/go.mod h1:jCHoyYQIJnaabEYnbGwyo9hUqfyUMTbJw/tAut5t97E= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -200,12 +200,12 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -go.etcd.io/etcd/api/v3 v3.5.11 h1:B54KwXbWDHyD3XYAwprxNzTe7vlhR69LuBgZnMVvS7E= -go.etcd.io/etcd/api/v3 v3.5.11/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= -go.etcd.io/etcd/client/pkg/v3 v3.5.11 h1:bT2xVspdiCj2910T0V+/KHcVKjkUrCZVtk8J2JF2z1A= -go.etcd.io/etcd/client/pkg/v3 v3.5.11/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= -go.etcd.io/etcd/client/v3 v3.5.11 h1:ajWtgoNSZJ1gmS8k+icvPtqsqEav+iUorF7b0qozgUU= -go.etcd.io/etcd/client/v3 v3.5.11/go.mod h1:a6xQUEqFJ8vztO1agJh/KQKOMfFI8og52ZconzcDJwE= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= @@ -246,8 +246,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -260,10 +260,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= +golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -284,12 +284,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -306,22 +306,22 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= @@ -341,12 +341,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= +k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= +k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= +k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= +k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= +k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= diff --git a/rest/config.go b/rest/config.go index ece29bfd..eb5fdb0b 100644 --- a/rest/config.go +++ b/rest/config.go @@ -53,7 +53,7 @@ type ( MaxBytes int64 `json:",default=1048576"` // milliseconds Timeout int64 `json:",default=3000"` - CpuThreshold int64 `json:",default=900,range=[0:1000]"` + CpuThreshold int64 `json:",default=900,range=[0:1000)"` Signature SignatureConf `json:",optional"` // There are default values for all the items in Middlewares. Middlewares MiddlewaresConf diff --git a/rest/handler/prometheushandler.go b/rest/handler/prometheushandler.go index 86676d4c..6abf4dee 100644 --- a/rest/handler/prometheushandler.go +++ b/rest/handler/prometheushandler.go @@ -18,7 +18,7 @@ var ( Name: "duration_ms", Help: "http server requests duration(ms).", Labels: []string{"path", "method"}, - Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000}, + Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 750, 1000}, }) metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{ diff --git a/rest/handler/timeouthandler.go b/rest/handler/timeouthandler.go index 25a98126..9a1b001d 100644 --- a/rest/handler/timeouthandler.go +++ b/rest/handler/timeouthandler.go @@ -24,6 +24,8 @@ const ( reason = "Request Timeout" headerUpgrade = "Upgrade" valueWebsocket = "websocket" + headerAccept = "Accept" + valueSSE = "text/event-stream" ) // TimeoutHandler returns the handler with given timeout. @@ -56,7 +58,9 @@ func (h *timeoutHandler) errorBody() string { } func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if r.Header.Get(headerUpgrade) == valueWebsocket { + if r.Header.Get(headerUpgrade) == valueWebsocket || + // Server-Sent Event ignore timeout. + r.Header.Get(headerAccept) == valueSSE { h.handler.ServeHTTP(w, r) return } @@ -110,7 +114,7 @@ func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } else { w.WriteHeader(http.StatusServiceUnavailable) } - io.WriteString(w, h.errorBody()) + _, _ = io.WriteString(w, h.errorBody()) }) tw.timedOut = true } diff --git a/rest/handler/timeouthandler_test.go b/rest/handler/timeouthandler_test.go index 0d96c592..f4f97d45 100644 --- a/rest/handler/timeouthandler_test.go +++ b/rest/handler/timeouthandler_test.go @@ -156,6 +156,23 @@ func TestTimeoutPanic(t *testing.T) { }) } +func TestTimeoutSSE(t *testing.T) { + timeoutHandler := TimeoutHandler(time.Millisecond) + handler := timeoutHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(time.Millisecond * 10) + r.Header.Set("Content-Type", "text/event-stream") + r.Header.Set("Cache-Control", "no-cache") + r.Header.Set("Connection", "keep-alive") + r.Header.Set("Transfer-Encoding", "chunked") + })) + + req := httptest.NewRequest(http.MethodGet, "http://localhost", nil) + req.Header.Set(headerAccept, valueSSE) + resp := httptest.NewRecorder() + handler.ServeHTTP(resp, req) + assert.Equal(t, http.StatusOK, resp.Code) +} + func TestTimeoutWebsocket(t *testing.T) { timeoutHandler := TimeoutHandler(time.Millisecond) handler := timeoutHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/rest/httpx/requests_test.go b/rest/httpx/requests_test.go index 57fe136f..a1d3f6a8 100644 --- a/rest/httpx/requests_test.go +++ b/rest/httpx/requests_test.go @@ -410,6 +410,18 @@ func TestParseWithFloatPtr(t *testing.T) { }) } +func TestParseWithEscapedParams(t *testing.T) { + t.Run("escaped", func(t *testing.T) { + var v struct { + Dev string `form:"dev"` + } + r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/api/v2/dev/test?dev=se205%5fy1205%5fj109%26verRelease=v01%26iid1=863494061186673%26iid2=863494061186681%26mcc=636%26mnc=1", http.NoBody) + if assert.NoError(t, Parse(r, &v)) { + assert.Equal(t, "se205_y1205_j109&verRelease=v01&iid1=863494061186673&iid2=863494061186681&mcc=636&mnc=1", v.Dev) + } + }) +} + func BenchmarkParseRaw(b *testing.B) { r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", http.NoBody) if err != nil { diff --git a/tools/goctl/go.mod b/tools/goctl/go.mod index 2e2a5bdb..00a7f1af 100644 --- a/tools/goctl/go.mod +++ b/tools/goctl/go.mod @@ -1,10 +1,12 @@ module github.com/zeromicro/go-zero/tools/goctl -go 1.19 +go 1.21 + +toolchain go1.21.5 require ( github.com/DATA-DOG/go-sqlmock v1.5.2 - github.com/emicklei/proto v1.13.0 + github.com/emicklei/proto v1.13.2 github.com/fatih/structtag v1.2.0 github.com/go-sql-driver/mysql v1.7.1 github.com/gookit/color v1.5.4 @@ -15,15 +17,15 @@ require ( github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 github.com/zeromicro/antlr v0.0.1 github.com/zeromicro/ddl-parser v1.0.5 - github.com/zeromicro/go-zero v1.6.1 + github.com/zeromicro/go-zero v1.6.2 golang.org/x/text v0.14.0 - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 ) require ( github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect - github.com/alicebob/miniredis/v2 v2.31.0 // indirect + github.com/alicebob/miniredis/v2 v2.31.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -32,27 +34,25 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.5.1 // indirect + github.com/jackc/pgx/v5 v5.5.2 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -60,23 +60,24 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/redis/go-redis/v9 v9.4.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect - go.etcd.io/etcd/api/v3 v3.5.11 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.11 // indirect - go.etcd.io/etcd/client/v3 v3.5.11 // indirect + go.etcd.io/etcd/api/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/v3 v3.5.12 // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect @@ -92,27 +93,27 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/oauth2 v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.28.4 // indirect - k8s.io/apimachinery v0.28.4 // indirect - k8s.io/client-go v0.28.4 // indirect - k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/api v0.29.1 // indirect + k8s.io/apimachinery v0.29.1 // indirect + k8s.io/client-go v0.29.1 // indirect + k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/tools/goctl/go.sum b/tools/goctl/go.sum index f5e64959..26455724 100644 --- a/tools/goctl/go.sum +++ b/tools/goctl/go.sum @@ -4,13 +4,15 @@ github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2Qc github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.31.0 h1:ObEFUNlJwoIiyjxdrYF0QIDE7qXcLc7D3WpSH4c22PU= -github.com/alicebob/miniredis/v2 v2.31.0/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= +github.com/alicebob/miniredis/v2 v2.31.1 h1:7XAt0uUg3DtwEKW5ZAGa+K7FZV2DdKQo5K/6TTnfX8Y= +github.com/alicebob/miniredis/v2 v2.31.1/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec h1:EEyRvzmpEUZ+I8WmD5cw/vY8EqhambkOqy5iFr0908A= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -29,20 +31,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.13.0 h1:YtC/om6EdkJ0me1JPw4h2g10k+ELITjYFb7tpzm8i8k= -github.com/emicklei/proto v1.13.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= +github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -52,8 +51,6 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -64,7 +61,6 @@ github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -72,14 +68,15 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= @@ -93,8 +90,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI= -github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.2 h1:iLlpgp4Cp/gC9Xuscl7lFL1PhhW+ZLtXZcrfCt4C3tA= +github.com/jackc/pgx/v5 v5.5.2/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -119,8 +116,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -128,26 +125,26 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk= +github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -181,14 +178,14 @@ github.com/zeromicro/antlr v0.0.1 h1:CQpIn/dc0pUjgGQ81y98s/NGOm2Hfru2NNio2I9mQgk github.com/zeromicro/antlr v0.0.1/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M= github.com/zeromicro/ddl-parser v1.0.5 h1:LaVqHdzMTjasua1yYpIYaksxKqRzFrEukj2Wi2EbWaQ= github.com/zeromicro/ddl-parser v1.0.5/go.mod h1:ISU/8NuPyEpl9pa17Py9TBPetMjtsiHrb9f5XGiYbo8= -github.com/zeromicro/go-zero v1.6.1 h1:E8fRkMPiYODk8+jUIrxQQIEG+MTgWfXKiH7sjc9l6Vs= -github.com/zeromicro/go-zero v1.6.1/go.mod h1:slLvzqPP/H/h9ABq9ykNOuX6pYLjA8Uy3Rb8adkXTGw= -go.etcd.io/etcd/api/v3 v3.5.11 h1:B54KwXbWDHyD3XYAwprxNzTe7vlhR69LuBgZnMVvS7E= -go.etcd.io/etcd/api/v3 v3.5.11/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= -go.etcd.io/etcd/client/pkg/v3 v3.5.11 h1:bT2xVspdiCj2910T0V+/KHcVKjkUrCZVtk8J2JF2z1A= -go.etcd.io/etcd/client/pkg/v3 v3.5.11/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= -go.etcd.io/etcd/client/v3 v3.5.11 h1:ajWtgoNSZJ1gmS8k+icvPtqsqEav+iUorF7b0qozgUU= -go.etcd.io/etcd/client/v3 v3.5.11/go.mod h1:a6xQUEqFJ8vztO1agJh/KQKOMfFI8og52ZconzcDJwE= +github.com/zeromicro/go-zero v1.6.2 h1:c1gXp6JTO0e+dtfwNZRE7OZgzjipfW8i1iBMoBnDwBI= +github.com/zeromicro/go-zero v1.6.2/go.mod h1:mQKK/c/er/sbIAo7DWyFBZX8oa0eOkc7QJdG15b2GBw= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= @@ -224,8 +221,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -237,11 +234,10 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= +golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -260,14 +256,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -282,21 +277,21 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= @@ -307,28 +302,27 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= -k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= -k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= -k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= -k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= -k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= +k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= +k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= +k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= +k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/tools/goctl/pkg/parser/api/parser/analyzer.go b/tools/goctl/pkg/parser/api/parser/analyzer.go index 236630e4..a08974a9 100644 --- a/tools/goctl/pkg/parser/api/parser/analyzer.go +++ b/tools/goctl/pkg/parser/api/parser/analyzer.go @@ -403,6 +403,9 @@ func Parse(filename string, src interface{}) (*spec.ApiSpec, error) { if err != nil { return nil, err } + if err := api.SelfCheck(); err != nil { + return nil, err + } var result = new(spec.ApiSpec) analyzer := Analyzer{ diff --git a/tools/goctl/pkg/parser/api/parser/analyzer_test.go b/tools/goctl/pkg/parser/api/parser/analyzer_test.go index de4193b6..5e01d0f4 100644 --- a/tools/goctl/pkg/parser/api/parser/analyzer_test.go +++ b/tools/goctl/pkg/parser/api/parser/analyzer_test.go @@ -42,4 +42,8 @@ func Test_Parse(t *testing.T) { _, err := Parse("./testdata/base.api", nil) assertx.Error(t, err) }) + t.Run("link_import", func(t *testing.T) { + _, err := Parse("./testdata/link_import.api", nil) + assert.Nil(t, err) + }) } diff --git a/tools/goctl/pkg/parser/api/parser/api.go b/tools/goctl/pkg/parser/api/parser/api.go index 6fc5584b..69d33b40 100644 --- a/tools/goctl/pkg/parser/api/parser/api.go +++ b/tools/goctl/pkg/parser/api/parser/api.go @@ -85,15 +85,12 @@ func convert2API(a *ast.AST, importSet map[string]lang.PlaceholderType, is *impo } } - if err := api.SelfCheck(); err != nil { - return nil, err - } return api, nil } func (api *API) checkImportStmt() error { f := newFilter() - b := f.addCheckItem("import value expression") + b := f.addCheckItem(api.Filename, "import value expression") for _, v := range api.importStmt { switch val := v.(type) { case *ast.ImportLiteralStmt: @@ -110,7 +107,7 @@ func (api *API) checkInfoStmt() error { return nil } f := newFilter() - b := f.addCheckItem("info key expression") + b := f.addCheckItem(api.Filename, "info key expression") for _, v := range api.info.Values { b.check(v.Key) } @@ -119,9 +116,9 @@ func (api *API) checkInfoStmt() error { func (api *API) checkServiceStmt() error { f := newFilter() - serviceNameChecker := f.addCheckItem("service name expression") - handlerChecker := f.addCheckItem("handler expression") - pathChecker := f.addCheckItem("path expression") + serviceNameChecker := f.addCheckItem(api.Filename, "service name expression") + handlerChecker := f.addCheckItem(api.Filename, "handler expression") + pathChecker := f.addCheckItem(api.Filename, "path expression") var serviceName = map[string]string{} for _, v := range api.ServiceStmts { name := strings.TrimSuffix(v.Name.Format(""), "-api") @@ -150,7 +147,7 @@ func (api *API) checkServiceStmt() error { func (api *API) checkTypeStmt() error { f := newFilter() - b := f.addCheckItem("type expression") + b := f.addCheckItem(api.Filename, "type expression") for _, v := range api.TypeStmt { switch val := v.(type) { case *ast.TypeLiteralStmt: diff --git a/tools/goctl/pkg/parser/api/parser/filter.go b/tools/goctl/pkg/parser/api/parser/filter.go index fd0ce0ae..b660f271 100644 --- a/tools/goctl/pkg/parser/api/parser/filter.go +++ b/tools/goctl/pkg/parser/api/parser/filter.go @@ -8,6 +8,7 @@ import ( ) type filterBuilder struct { + filename string m map[string]placeholder.Type checkExprName string errorManager *errorManager @@ -15,10 +16,11 @@ type filterBuilder struct { func (b *filterBuilder) check(nodes ...*ast.TokenNode) { for _, node := range nodes { - if _, ok := b.m[node.Token.Text]; ok { + fileNodeText := fmt.Sprintf("%s/%s", b.filename, node.Token.Text) + if _, ok := b.m[fileNodeText]; ok { b.errorManager.add(ast.DuplicateStmtError(node.Pos(), "duplicate "+b.checkExprName)) } else { - b.m[node.Token.Text] = placeholder.PlaceHolder + b.m[fileNodeText] = placeholder.PlaceHolder } } } @@ -46,8 +48,9 @@ func newFilter() *filter { return &filter{} } -func (f *filter) addCheckItem(checkExprName string) *filterBuilder { +func (f *filter) addCheckItem(filename, checkExprName string) *filterBuilder { b := &filterBuilder{ + filename: filename, m: make(map[string]placeholder.Type), checkExprName: checkExprName, errorManager: newErrorManager(), diff --git a/tools/goctl/pkg/parser/api/parser/testdata/base/request.api b/tools/goctl/pkg/parser/api/parser/testdata/base/request.api new file mode 100644 index 00000000..fc1f3ac9 --- /dev/null +++ b/tools/goctl/pkg/parser/api/parser/testdata/base/request.api @@ -0,0 +1,6 @@ +syntax = "v1" + +type Baz { + Foo string `json:"foo"` + Baz bool `json:"bar"` +} diff --git a/tools/goctl/pkg/parser/api/parser/testdata/base/response.api b/tools/goctl/pkg/parser/api/parser/testdata/base/response.api new file mode 100644 index 00000000..83091190 --- /dev/null +++ b/tools/goctl/pkg/parser/api/parser/testdata/base/response.api @@ -0,0 +1,10 @@ +syntax = "v1" + +import "request.api" +type Bar { + Foo int `json:"foo"` + Bar bool `json:"bar"` + Baz + Qux map[string]string `json:"qux"` +} + diff --git a/tools/goctl/pkg/parser/api/parser/testdata/link_import.api b/tools/goctl/pkg/parser/api/parser/testdata/link_import.api new file mode 100644 index 00000000..fb08003f --- /dev/null +++ b/tools/goctl/pkg/parser/api/parser/testdata/link_import.api @@ -0,0 +1,12 @@ +syntax = "v1" + +import "base/request.api" +import "base/response.api" + +type Foo {} + +service demo { + @handler handlerName + get /users/id/:userId (Baz) returns (Bar) +} + diff --git a/zrpc/config.go b/zrpc/config.go index 84a32160..5e459a3c 100644 --- a/zrpc/config.go +++ b/zrpc/config.go @@ -43,7 +43,7 @@ type ( StrictControl bool `json:",optional"` // setting 0 means no timeout Timeout int64 `json:",default=2000"` - CpuThreshold int64 `json:",default=900,range=[0:1000]"` + CpuThreshold int64 `json:",default=900,range=[0:1000)"` // grpc health check switch Health bool `json:",default=true"` Middlewares ServerMiddlewaresConf diff --git a/zrpc/internal/serverinterceptors/breakerinterceptor_test.go b/zrpc/internal/serverinterceptors/breakerinterceptor_test.go index 26538c27..58662de2 100644 --- a/zrpc/internal/serverinterceptors/breakerinterceptor_test.go +++ b/zrpc/internal/serverinterceptors/breakerinterceptor_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/zeromicro/go-zero/core/breaker" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -27,3 +28,12 @@ func TestUnaryBreakerInterceptor(t *testing.T) { }) assert.NotNil(t, err) } + +func TestUnaryBreakerInterceptor_Unavailable(t *testing.T) { + _, err := UnaryBreakerInterceptor(context.Background(), nil, &grpc.UnaryServerInfo{ + FullMethod: "any", + }, func(_ context.Context, _ any) (any, error) { + return nil, breaker.ErrServiceUnavailable + }) + assert.NotNil(t, err) +}