go.uber.org/yarpc@v1.72.1/encoding/thrift/thriftrw-plugin-yarpc/client.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 main 22 23 import ( 24 "path/filepath" 25 26 "go.uber.org/thriftrw/plugin" 27 ) 28 29 const clientTemplate = ` 30 // Code generated by thriftrw-plugin-yarpc 31 // @generated 32 33 <$pkgname := printf "%sclient" (lower .Name)> 34 package <$pkgname> 35 36 <$yarpc := import "go.uber.org/yarpc"> 37 <$transport := import "go.uber.org/yarpc/api/transport"> 38 <$thrift := import "go.uber.org/yarpc/encoding/thrift"> 39 40 </* Note that we import things like "context" inside loops rather than at the 41 top-level because they will end up unused if the service does not have any 42 functions. 43 */> 44 45 // Interface is a client for the <.Name> service. 46 type Interface interface { 47 <if .Parent><import .ParentClientPackagePath>.Interface 48 <end> 49 <range .Functions> 50 <$context := import "context"> 51 <.Name>( 52 ctx <$context>.Context, <range .Arguments> 53 <.Name> <formatType .Type>,<end> 54 opts ...<$yarpc>.CallOption, 55 )<if .OneWay> (<$yarpc>.Ack, error) 56 <else if .ReturnType> (<formatType .ReturnType>, error) 57 <else> error 58 <end> 59 <end> 60 } 61 62 </* TODO(abg): Pull the default routing name from a Thrift annotation? */> 63 64 // New builds a new client for the <.Name> service. 65 // 66 // client := <$pkgname>.New(dispatcher.ClientConfig("<lower .Name>")) 67 func New(c <$transport>.ClientConfig, opts ...<$thrift>.ClientOption) Interface { 68 return client{ 69 c: <$thrift>.New(<$thrift>.Config{ 70 Service: "<.Name>", 71 ClientConfig: c, 72 }, opts...), 73 nwc: <$thrift>.NewNoWire(<$thrift>.Config{ 74 Service: "<.Name>", 75 ClientConfig: c, 76 }, opts...), 77 <if .Parent> 78 Interface: <import .ParentClientPackagePath>.New( 79 c, 80 append( 81 opts, 82 <$thrift>.Named("<.Name>"), 83 )..., 84 ), 85 <end> 86 } 87 } 88 89 90 func init() { 91 <$yarpc>.RegisterClientBuilder( 92 func(c <$transport>.ClientConfig, f <import "reflect">.StructField) Interface { 93 return New(c, <$thrift>.ClientBuilderOptions(c, f)...) 94 }, 95 ) 96 } 97 98 type client struct { 99 <if .Parent><import .ParentClientPackagePath>.Interface 100 <end> 101 c <$thrift>.Client 102 nwc <$thrift>.NoWireClient 103 } 104 105 <$service := .> 106 <$module := .Module> 107 <$sanitize := .SanitizeTChannel> 108 <range .Functions> 109 <$context := import "context"> 110 <$prefix := printf "%s.%s_%s_" (import $module.ImportPath) $service.Name .Name> 111 112 func (c client) <.Name>( 113 ctx <$context>.Context, <range .Arguments> 114 _<.Name> <formatType .Type>,<end> 115 opts ...<$yarpc>.CallOption, 116 <if .OneWay>) (<$yarpc>.Ack, error) { 117 args := <$prefix>Helper.Args(<range .Arguments>_<.Name>, <end>) 118 return c.c.CallOneway(ctx, args, opts...) 119 } 120 <else>) (<if .ReturnType>success <formatType .ReturnType>,<end> err error) { 121 <$wire := import "go.uber.org/thriftrw/wire"> 122 var result <$prefix>Result 123 args := <$prefix>Helper.Args(<range .Arguments>_<.Name>, <end>) 124 125 <if $sanitize>ctx = <import "github.com/uber/tchannel-go">.WithoutHeaders(ctx)<end> 126 if c.nwc != nil && c.nwc.Enabled() { 127 if err = c.nwc.Call(ctx, args, &result, opts...); err != nil { 128 return 129 } 130 } else { 131 var body <$wire>.Value 132 if body, err = c.c.Call(ctx, args, opts...); err != nil { 133 return 134 } 135 136 if err = result.FromWire(body); err != nil { 137 return 138 } 139 } 140 141 <if .ReturnType>success, <end>err = <$prefix>Helper.UnwrapResponse(&result) 142 return 143 } 144 <end> 145 <end> 146 ` 147 148 func clientGenerator(data *serviceTemplateData, files map[string][]byte) (err error) { 149 packageName := filepath.Base(data.ClientPackagePath()) 150 // kv.thrift => .../kv/keyvalueclient/client.go 151 path := filepath.Join(data.Module.Directory, packageName, "client.go") 152 files[path], err = plugin.GoFileFromTemplate(path, clientTemplate, data, templateOptions...) 153 return 154 }