github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/default_client_handler.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package trans 18 19 import ( 20 "context" 21 "net" 22 23 "github.com/cloudwego/kitex/pkg/kerrors" 24 "github.com/cloudwego/kitex/pkg/klog" 25 "github.com/cloudwego/kitex/pkg/remote" 26 "github.com/cloudwego/kitex/pkg/rpcinfo" 27 "github.com/cloudwego/kitex/pkg/stats" 28 ) 29 30 // NewDefaultCliTransHandler to provide default impl of cliTransHandler, it can be reused in netpoll, shm-ipc, framework-sdk extensions 31 func NewDefaultCliTransHandler(opt *remote.ClientOption, ext Extension) (remote.ClientTransHandler, error) { 32 return &cliTransHandler{ 33 opt: opt, 34 codec: opt.Codec, 35 ext: ext, 36 }, nil 37 } 38 39 type cliTransHandler struct { 40 opt *remote.ClientOption 41 codec remote.Codec 42 transPipe *remote.TransPipeline 43 ext Extension 44 } 45 46 // Write implements the remote.ClientTransHandler interface. 47 func (t *cliTransHandler) Write(ctx context.Context, conn net.Conn, sendMsg remote.Message) (nctx context.Context, err error) { 48 var bufWriter remote.ByteBuffer 49 rpcinfo.Record(ctx, sendMsg.RPCInfo(), stats.WriteStart, nil) 50 defer func() { 51 t.ext.ReleaseBuffer(bufWriter, err) 52 rpcinfo.Record(ctx, sendMsg.RPCInfo(), stats.WriteFinish, err) 53 }() 54 55 bufWriter = t.ext.NewWriteByteBuffer(ctx, conn, sendMsg) 56 sendMsg.SetPayloadCodec(t.opt.PayloadCodec) 57 err = t.codec.Encode(ctx, sendMsg, bufWriter) 58 if err != nil { 59 return ctx, err 60 } 61 return ctx, bufWriter.Flush() 62 } 63 64 // Read implements the remote.ClientTransHandler interface. 65 func (t *cliTransHandler) Read(ctx context.Context, conn net.Conn, recvMsg remote.Message) (nctx context.Context, err error) { 66 var bufReader remote.ByteBuffer 67 rpcinfo.Record(ctx, recvMsg.RPCInfo(), stats.ReadStart, nil) 68 defer func() { 69 t.ext.ReleaseBuffer(bufReader, err) 70 rpcinfo.Record(ctx, recvMsg.RPCInfo(), stats.ReadFinish, err) 71 }() 72 73 t.ext.SetReadTimeout(ctx, conn, recvMsg.RPCInfo().Config(), recvMsg.RPCRole()) 74 bufReader = t.ext.NewReadByteBuffer(ctx, conn, recvMsg) 75 recvMsg.SetPayloadCodec(t.opt.PayloadCodec) 76 err = t.codec.Decode(ctx, recvMsg, bufReader) 77 if err != nil { 78 if t.ext.IsTimeoutErr(err) { 79 err = kerrors.ErrRPCTimeout.WithCause(err) 80 } 81 return ctx, err 82 } 83 84 return ctx, nil 85 } 86 87 // OnMessage implements the remote.ClientTransHandler interface. 88 func (t *cliTransHandler) OnMessage(ctx context.Context, args, result remote.Message) (context.Context, error) { 89 // do nothing 90 return ctx, nil 91 } 92 93 // OnInactive implements the remote.ClientTransHandler interface. 94 func (t *cliTransHandler) OnInactive(ctx context.Context, conn net.Conn) { 95 // ineffective now and do nothing 96 } 97 98 // OnError implements the remote.ClientTransHandler interface. 99 func (t *cliTransHandler) OnError(ctx context.Context, err error, conn net.Conn) { 100 if pe, ok := err.(*kerrors.DetailedError); ok { 101 klog.CtxErrorf(ctx, "KITEX: send request error, remote=%s, error=%s\nstack=%s", conn.RemoteAddr(), err.Error(), pe.Stack()) 102 } else { 103 klog.CtxErrorf(ctx, "KITEX: send request error, remote=%s, error=%s", conn.RemoteAddr(), err.Error()) 104 } 105 } 106 107 // SetPipeline implements the remote.ClientTransHandler interface. 108 func (t *cliTransHandler) SetPipeline(p *remote.TransPipeline) { 109 t.transPipe = p 110 }