12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- /*
- *
- * Copyright 2020 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- package testutils
- import (
- "fmt"
- "sync"
- "google.golang.org/grpc/internal/wrr"
- )
- // testWRR is a deterministic WRR implementation.
- //
- // The real implementation does random WRR. testWRR makes the balancer behavior
- // deterministic and easier to test.
- //
- // With {a: 2, b: 3}, the Next() results will be {a, a, b, b, b}.
- type testWRR struct {
- itemsWithWeight []struct {
- item interface{}
- weight int64
- }
- length int
- mu sync.Mutex
- idx int // The index of the item that will be picked
- count int64 // The number of times the current item has been picked.
- }
- // NewTestWRR return a WRR for testing. It's deterministic instead of random.
- func NewTestWRR() wrr.WRR {
- return &testWRR{}
- }
- func (twrr *testWRR) Add(item interface{}, weight int64) {
- twrr.itemsWithWeight = append(twrr.itemsWithWeight, struct {
- item interface{}
- weight int64
- }{item: item, weight: weight})
- twrr.length++
- }
- func (twrr *testWRR) Next() interface{} {
- twrr.mu.Lock()
- iww := twrr.itemsWithWeight[twrr.idx]
- twrr.count++
- if twrr.count >= iww.weight {
- twrr.idx = (twrr.idx + 1) % twrr.length
- twrr.count = 0
- }
- twrr.mu.Unlock()
- return iww.item
- }
- func (twrr *testWRR) String() string {
- return fmt.Sprint(twrr.itemsWithWeight)
- }
|