github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/testutils/wrr.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package testutils 20 21 import ( 22 "fmt" 23 "sync" 24 25 "github.com/hxx258456/ccgo/grpc/internal/wrr" 26 ) 27 28 // testWRR is a deterministic WRR implementation. 29 // 30 // The real implementation does random WRR. testWRR makes the balancer behavior 31 // deterministic and easier to test. 32 // 33 // With {a: 2, b: 3}, the Next() results will be {a, a, b, b, b}. 34 type testWRR struct { 35 itemsWithWeight []struct { 36 item interface{} 37 weight int64 38 } 39 length int 40 41 mu sync.Mutex 42 idx int // The index of the item that will be picked 43 count int64 // The number of times the current item has been picked. 44 } 45 46 // NewTestWRR return a WRR for testing. It's deterministic instead of random. 47 func NewTestWRR() wrr.WRR { 48 return &testWRR{} 49 } 50 51 func (twrr *testWRR) Add(item interface{}, weight int64) { 52 twrr.itemsWithWeight = append(twrr.itemsWithWeight, struct { 53 item interface{} 54 weight int64 55 }{item: item, weight: weight}) 56 twrr.length++ 57 } 58 59 func (twrr *testWRR) Next() interface{} { 60 twrr.mu.Lock() 61 iww := twrr.itemsWithWeight[twrr.idx] 62 twrr.count++ 63 if twrr.count >= iww.weight { 64 twrr.idx = (twrr.idx + 1) % twrr.length 65 twrr.count = 0 66 } 67 twrr.mu.Unlock() 68 return iww.item 69 } 70 71 func (twrr *testWRR) String() string { 72 return fmt.Sprint(twrr.itemsWithWeight) 73 }