github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/balancer/rls/internal/child_policy.go (about) 1 /* 2 * 3 * Copyright 2021 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 rls 20 21 import ( 22 "fmt" 23 "sync/atomic" 24 "unsafe" 25 26 "github.com/hxx258456/ccgo/grpc/balancer" 27 "github.com/hxx258456/ccgo/grpc/balancer/base" 28 "github.com/hxx258456/ccgo/grpc/connectivity" 29 internalgrpclog "github.com/hxx258456/ccgo/grpc/internal/grpclog" 30 ) 31 32 // TODO(easwars): Remove this once all RLS code is merged. 33 //lint:file-ignore U1000 Ignore all unused code, not all code is merged yet. 34 35 // childPolicyWrapper is a reference counted wrapper around a child policy. 36 // 37 // The LB policy maintains a map of these wrappers keyed by the target returned 38 // by RLS. When a target is seen for the first time, a child policy wrapper is 39 // created for it and the wrapper is added to the child policy map. Each entry 40 // in the data cache holds references to the corresponding child policy 41 // wrappers. The LB policy also holds a reference to the child policy wrapper 42 // for the default target specified in the LB Policy Configuration 43 // 44 // When a cache entry is evicted, it releases references to the child policy 45 // wrappers that it contains. When all references have been released, the 46 // wrapper is removed from the child policy map and is destroyed. 47 // 48 // The child policy wrapper also caches the connectivity state and most recent 49 // picker from the child policy. Once the child policy wrapper reports 50 // TRANSIENT_FAILURE, it will continue reporting that state until it goes READY; 51 // transitions from TRANSIENT_FAILURE to CONNECTING are ignored. 52 // 53 // Whenever a child policy wrapper changes its connectivity state, the LB policy 54 // returns a new picker to the channel, since the channel may need to re-process 55 // the picks for queued RPCs. 56 // 57 // It is not safe for concurrent access. 58 type childPolicyWrapper struct { 59 logger *internalgrpclog.PrefixLogger 60 target string // RLS target corresponding to this child policy. 61 refCnt int // Reference count. 62 63 // Balancer state reported by the child policy. The RLS LB policy maintains 64 // these child policies in a BalancerGroup. The state reported by the child 65 // policy is pushed to the state aggregator (which is also implemented by the 66 // RLS LB policy) and cached here. See handleChildPolicyStateUpdate() for 67 // details on how the state aggregation is performed. 68 // 69 // While this field is written to by the LB policy, it is read by the picker 70 // at Pick time. Making this an atomic to enable the picker to read this value 71 // without a mutex. 72 state unsafe.Pointer // *balancer.State 73 } 74 75 // newChildPolicyWrapper creates a child policy wrapper for the given target, 76 // and is initialized with one reference and starts off in CONNECTING state. 77 func newChildPolicyWrapper(target string) *childPolicyWrapper { 78 c := &childPolicyWrapper{ 79 target: target, 80 refCnt: 1, 81 state: unsafe.Pointer(&balancer.State{ 82 ConnectivityState: connectivity.Connecting, 83 Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable), 84 }), 85 } 86 c.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[rls-child-policy-wrapper %s %p] ", c.target, c)) 87 c.logger.Infof("Created") 88 return c 89 } 90 91 // acquireRef increments the reference count on the child policy wrapper. 92 func (c *childPolicyWrapper) acquireRef() { 93 c.refCnt++ 94 } 95 96 // releaseRef decrements the reference count on the child policy wrapper. The 97 // return value indicates whether the released reference was the last one. 98 func (c *childPolicyWrapper) releaseRef() bool { 99 c.refCnt-- 100 return c.refCnt == 0 101 } 102 103 // lamify causes the child policy wrapper to return a picker which will always 104 // fail requests. This is used when the wrapper runs into errors when trying to 105 // build and parse the child policy configuration. 106 func (c *childPolicyWrapper) lamify(err error) { 107 c.logger.Warningf("Entering lame mode: %v", err) 108 atomic.StorePointer(&c.state, unsafe.Pointer(&balancer.State{ 109 ConnectivityState: connectivity.TransientFailure, 110 Picker: base.NewErrPicker(err), 111 })) 112 }