@@ -194,11 +194,6 @@ func (c *defaultCodec) DecodeMeta(ctx context.Context, message remote.Message, i
194194 if flagBuf , err = in .Peek (2 * Size32 ); err != nil {
195195 return perrors .NewProtocolErrorWithErrMsg (err , fmt .Sprintf ("default codec read failed: %s" , err .Error ()))
196196 }
197-
198- if err = checkRPCState (ctx , message ); err != nil {
199- // there is one call has finished in retry task, it doesn't need to do decode for this call
200- return err
201- }
202197 isTTHeader := IsTTHeader (flagBuf )
203198 // 1. decode header
204199 if isTTHeader {
@@ -254,6 +249,11 @@ func (c *defaultCodec) DecodePayload(ctx context.Context, message remote.Message
254249
255250// Decode implements the remote.Codec interface, it does complete message decode include header and payload.
256251func (c * defaultCodec ) Decode (ctx context.Context , message remote.Message , in remote.ByteBuffer ) (err error ) {
252+ defer updateRPCDecodeState (ctx , message , err )
253+ if err = checkRPCState (ctx , message ); err != nil {
254+ // there is one call has finished in retry task, it doesn't need to do decode for this call
255+ return err
256+ }
257257 // 1. decode meta
258258 if err = c .DecodeMeta (ctx , message , in ); err != nil {
259259 return err
@@ -381,6 +381,8 @@ func isThriftFramedBinary(flagBuf []byte) bool {
381381 return binary .BigEndian .Uint32 (flagBuf [Size32 :])& MagicMask == ThriftV1Magic
382382}
383383
384+ // checkRPCState is used to avoid concurrent decoding situations
385+ // specific situation: request retry and timeout
384386func checkRPCState (ctx context.Context , message remote.Message ) error {
385387 if message .RPCRole () == remote .Server {
386388 return nil
@@ -398,6 +400,23 @@ func checkRPCState(ctx context.Context, message remote.Message) error {
398400 return nil
399401}
400402
403+ // updateRPCDecodeState is used to update the decoding status on the client side, which is for retry scenarios.
404+ // If decoding is completed, update CtxRespOp to OpDone.
405+ // Note that the update will only occur when it is actually encoded, if it is returned by ErrRPCFinal, it cannot be updated
406+ func updateRPCDecodeState (ctx context.Context , message remote.Message , err error ) {
407+ if err == kerrors .ErrRPCFinish {
408+ fmt .Println ("ErrRPCFinish 不更新" )
409+ return
410+ }
411+ if message .RPCRole () == remote .Server {
412+ return
413+ }
414+ if respOp , ok := ctx .Value (retry .CtxRespOp ).(* int32 ); ok {
415+ atomic .CompareAndSwapInt32 (respOp , retry .OpDoing , retry .OpDone )
416+ }
417+ return
418+ }
419+
401420func checkPayload (flagBuf []byte , message remote.Message , in remote.ByteBuffer , isTTHeader bool , maxPayloadSize int ) error {
402421 var transProto transport.Protocol
403422 var codecType serviceinfo.PayloadCodec
0 commit comments