go.uber.org/yarpc@v1.72.1/api/transport/handler.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 transport 22 23 import ( 24 "context" 25 "time" 26 27 "go.uber.org/zap/zapcore" 28 ) 29 30 // Type is an enum of RPC types 31 type Type int 32 33 const ( 34 // Unary types are traditional request/response RPCs 35 Unary Type = iota + 1 36 // Oneway types are fire and forget RPCs (no response) 37 Oneway 38 // Streaming types are Stream based RPCs (bidirectional messages over long 39 // lived connections) 40 Streaming 41 ) 42 43 // HandlerSpec holds a handler and its Type 44 // one handler will be set, the other nil 45 type HandlerSpec struct { 46 t Type 47 48 unaryHandler UnaryHandler 49 onewayHandler OnewayHandler 50 streamHandler StreamHandler 51 } 52 53 // MarshalLogObject implements zap.ObjectMarshaler. 54 func (h HandlerSpec) MarshalLogObject(enc zapcore.ObjectEncoder) error { 55 enc.AddString("rpcType", h.t.String()) 56 return nil 57 } 58 59 // Type returns the associated handler's type 60 func (h HandlerSpec) Type() Type { return h.t } 61 62 // Unary returns the Unary Handler or nil 63 func (h HandlerSpec) Unary() UnaryHandler { return h.unaryHandler } 64 65 // Oneway returns the Oneway Handler or nil 66 func (h HandlerSpec) Oneway() OnewayHandler { return h.onewayHandler } 67 68 // Stream returns the Stream Handler or nil 69 func (h HandlerSpec) Stream() StreamHandler { return h.streamHandler } 70 71 // NewUnaryHandlerSpec returns an new HandlerSpec with a UnaryHandler 72 func NewUnaryHandlerSpec(handler UnaryHandler) HandlerSpec { 73 return HandlerSpec{t: Unary, unaryHandler: handler} 74 } 75 76 // NewOnewayHandlerSpec returns an new HandlerSpec with a OnewayHandler 77 func NewOnewayHandlerSpec(handler OnewayHandler) HandlerSpec { 78 return HandlerSpec{t: Oneway, onewayHandler: handler} 79 } 80 81 // NewStreamHandlerSpec returns an new HandlerSpec with a StreamHandler 82 func NewStreamHandlerSpec(handler StreamHandler) HandlerSpec { 83 return HandlerSpec{t: Streaming, streamHandler: handler} 84 } 85 86 // UnaryHandler handles a single, transport-level, unary request. 87 type UnaryHandler interface { 88 // Handle the given request, writing the response to the given 89 // ResponseWriter. 90 // 91 // An error may be returned in case of failures. BadRequestError must be 92 // returned for invalid requests. All other failures are treated as 93 // UnexpectedErrors. 94 // 95 // Handlers MUST NOT retain references to the ResponseWriter. 96 Handle(ctx context.Context, req *Request, resw ResponseWriter) error 97 } 98 99 // OnewayHandler handles a single, transport-level, oneway request. 100 type OnewayHandler interface { 101 // Handle the given oneway request 102 // 103 // An error may be returned in case of failures. 104 HandleOneway(ctx context.Context, req *Request) error 105 } 106 107 // StreamHandler handles a stream connection request. 108 type StreamHandler interface { 109 // Handle the given stream connection. The stream will close when the 110 // function returns. 111 // 112 // An error may be returned in case of failures. 113 HandleStream(stream *ServerStream) error 114 } 115 116 // DispatchUnaryHandler calls the handler h, recovering panics and timeout errors, 117 // converting them to yarpc errors. All other errors are passed trough. 118 // 119 // Deprecated: Use InvokeUnaryHandler instead. 120 func DispatchUnaryHandler( 121 ctx context.Context, 122 h UnaryHandler, 123 start time.Time, 124 req *Request, 125 resq ResponseWriter, 126 ) (err error) { 127 return InvokeUnaryHandler(UnaryInvokeRequest{ 128 Context: ctx, 129 StartTime: start, 130 Request: req, 131 ResponseWriter: resq, 132 Handler: h, 133 }) 134 } 135 136 // DispatchOnewayHandler calls the oneway handler, recovering from panics as 137 // errors 138 // 139 // Deprecated: Use InvokeOnewayHandler instead. 140 func DispatchOnewayHandler( 141 ctx context.Context, 142 h OnewayHandler, 143 req *Request, 144 ) (err error) { 145 return InvokeOnewayHandler(OnewayInvokeRequest{ 146 Context: ctx, 147 Request: req, 148 Handler: h, 149 }) 150 } 151 152 // DispatchStreamHandler calls the stream handler, recovering from panics as 153 // errors. 154 // 155 // Deprecated: Use InvokeStreamHandler instead. 156 func DispatchStreamHandler( 157 h StreamHandler, 158 stream *ServerStream, 159 ) (err error) { 160 return InvokeStreamHandler(StreamInvokeRequest{ 161 Stream: stream, 162 Handler: h, 163 }) 164 }