go.uber.org/yarpc@v1.72.1/yarpcconfig/kit.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package yarpcconfig 22 23 import ( 24 "errors" 25 "fmt" 26 "reflect" 27 "sort" 28 "strings" 29 30 "go.uber.org/yarpc/api/transport" 31 "go.uber.org/yarpc/internal/interpolate" 32 ) 33 34 // Kit is an opaque object that carries context for the Configurator. Build 35 // functions that receive this object MUST NOT modify it. 36 type Kit struct { 37 c *Configurator 38 39 name string 40 41 // outboundName is the name of the outbound. It is set in the Kit used for 42 // building outbound. 43 outboundName string 44 45 // Used to resolve interpolated variables. 46 resolver interpolate.VariableResolver 47 48 // TransportSpec currently being used. This may or may not be set. 49 transportSpec *compiledTransportSpec 50 } 51 52 // Returns a shallow copy of this Kit with spec set to the given value. 53 func (k *Kit) withTransportSpec(spec *compiledTransportSpec) *Kit { 54 newK := *k 55 newK.transportSpec = spec 56 return &newK 57 } 58 59 // Returns a shallow copy of this Kit with outbound name set to given value. 60 func (k *Kit) withOutboundName(name string) *Kit { 61 newK := *k 62 newK.outboundName = name 63 return &newK 64 } 65 66 // ServiceName returns the name of the service for which components are being 67 // built. 68 func (k *Kit) ServiceName() string { return k.name } 69 70 // OutboundServiceName returns the name of the service for which outbound is 71 // being built. 72 func (k *Kit) OutboundServiceName() string { return k.outboundName } 73 74 var _typeOfKit = reflect.TypeOf((*Kit)(nil)) 75 76 func (k *Kit) maybePeerChooserSpec(name string) *compiledPeerChooserSpec { 77 return k.c.knownPeerChoosers[name] 78 } 79 80 func (k *Kit) peerListSpec(name string) (*compiledPeerListSpec, error) { 81 if spec := k.c.knownPeerLists[name]; spec != nil { 82 return spec, nil 83 } 84 85 msg := fmt.Sprintf("no recognized peer list or chooser %q", name) 86 if available := k.peerChooserAndListSpecNames(); len(available) > 0 { 87 msg = fmt.Sprintf("%s; need one of %s", msg, strings.Join(available, ", ")) 88 } 89 90 return nil, errors.New(msg) 91 } 92 93 func (k *Kit) peerChooserPreset(name string) (*compiledPeerChooserPreset, error) { 94 if k.transportSpec == nil { 95 // Currently, transportspec is set only if we're inside build*Outbound. 96 return nil, errors.New( 97 "invalid Kit: make sure you passed in the same Kit your Build function received") 98 } 99 100 if spec := k.transportSpec.PeerChooserPresets[name]; spec != nil { 101 return spec, nil 102 } 103 104 available := make([]string, 0, len(k.transportSpec.PeerChooserPresets)) 105 for name := range k.transportSpec.PeerChooserPresets { 106 available = append(available, name) 107 } 108 109 msg := fmt.Sprintf("no recognized peer chooser preset %q", name) 110 if len(available) > 0 { 111 msg = fmt.Sprintf("%s; need one of %s", msg, strings.Join(available, ", ")) 112 } 113 114 return nil, errors.New(msg) 115 } 116 117 func (k *Kit) peerChooserAndListSpecNames() (names []string) { 118 for name := range k.c.knownPeerLists { 119 names = append(names, name) 120 } 121 for name := range k.c.knownPeerChoosers { 122 names = append(names, name) 123 } 124 sort.Strings(names) 125 return 126 } 127 128 func (k *Kit) peerListUpdaterSpec(name string) *compiledPeerListUpdaterSpec { 129 return k.c.knownPeerListUpdaters[name] 130 } 131 132 func (k *Kit) peerListUpdaterSpecNames() (names []string) { 133 for name := range k.c.knownPeerListUpdaters { 134 names = append(names, name) 135 } 136 sort.Strings(names) 137 return 138 } 139 140 // Compressor returns the known compressor for the given name or nil if the 141 // named compressor is not known. 142 func (k *Kit) Compressor(name string) transport.Compressor { 143 return k.c.knownCompressors[name] 144 }