github.com/cloudwego/kitex@v0.9.0/pkg/limiter/connection_limiter.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package limiter 18 19 import ( 20 "context" 21 "sync/atomic" 22 ) 23 24 // connectionLimiter implements ConcurrencyLimiter. 25 type connectionLimiter struct { 26 lim int32 27 curr int32 28 } 29 30 // NewConnectionLimiter returns a new ConnectionLimiter with the given limit. 31 func NewConnectionLimiter(lim int) ConcurrencyLimiter { 32 return &connectionLimiter{int32(lim), 0} 33 } 34 35 // Deprecated: Use NewConnectionLimiter instead. 36 func NewConcurrencyLimiter(lim int) ConcurrencyLimiter { 37 return &connectionLimiter{int32(lim), 0} 38 } 39 40 // Acquire tries to increase the connection counter. 41 // The return value indicates whether the operation is allowed under the connection limitation. 42 // Acquired is executed in `OnActive` which is called when a new connection is accepted, so even if the limit is reached 43 // the count is still need increase, but return false will lead the connection is closed then Release also be executed. 44 func (ml *connectionLimiter) Acquire(ctx context.Context) bool { 45 limit := atomic.LoadInt32(&ml.lim) 46 x := atomic.AddInt32(&ml.curr, 1) 47 return x <= limit || limit <= 0 48 } 49 50 // Release decrease the connection counter. 51 func (ml *connectionLimiter) Release(ctx context.Context) { 52 atomic.AddInt32(&ml.curr, -1) 53 } 54 55 // UpdateLimit updates the limit. 56 func (ml *connectionLimiter) UpdateLimit(lim int) { 57 atomic.StoreInt32(&ml.lim, int32(lim)) 58 } 59 60 // Status returns the current status. 61 func (ml *connectionLimiter) Status(ctx context.Context) (limit, occupied int) { 62 limit = int(atomic.LoadInt32(&ml.lim)) 63 occupied = int(atomic.LoadInt32(&ml.curr)) 64 return 65 }