github.com/cloudwego/kitex@v0.9.0/pkg/rpcinfo/rpcconfig.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 rpcinfo
    18  
    19  import (
    20  	"sync"
    21  	"time"
    22  
    23  	"github.com/cloudwego/kitex/pkg/kerrors"
    24  	"github.com/cloudwego/kitex/pkg/serviceinfo"
    25  	"github.com/cloudwego/kitex/transport"
    26  )
    27  
    28  var (
    29  	_             MutableRPCConfig = &rpcConfig{}
    30  	_             RPCConfig        = &rpcConfig{}
    31  	rpcConfigPool sync.Pool
    32  )
    33  
    34  // default values.
    35  var (
    36  	defaultRPCTimeout       = time.Duration(0)
    37  	defaultConnectTimeout   = time.Millisecond * 50
    38  	defaultReadWriteTimeout = time.Second * 5
    39  	defaultBufferSize       = 4096
    40  	defaultInteractionMode  = PingPong
    41  )
    42  
    43  // Mask bits.
    44  const (
    45  	BitRPCTimeout = 1 << iota
    46  	BitConnectTimeout
    47  	BitReadWriteTimeout
    48  	BitIOBufferSize
    49  )
    50  
    51  type InteractionMode int32
    52  
    53  const (
    54  	PingPong  InteractionMode = 0
    55  	Oneway    InteractionMode = 1
    56  	Streaming InteractionMode = 2
    57  )
    58  
    59  // rpcConfig is a set of configurations used during RPC calls.
    60  type rpcConfig struct {
    61  	readOnlyMask      int
    62  	rpcTimeout        time.Duration
    63  	connectTimeout    time.Duration
    64  	readWriteTimeout  time.Duration
    65  	ioBufferSize      int
    66  	transportProtocol transport.Protocol
    67  	interactionMode   InteractionMode
    68  	payloadCodec      serviceinfo.PayloadCodec
    69  }
    70  
    71  func init() {
    72  	rpcConfigPool.New = newRPCConfig
    73  }
    74  
    75  func newRPCConfig() interface{} {
    76  	c := &rpcConfig{}
    77  	c.initialize()
    78  	return c
    79  }
    80  
    81  // LockConfig sets the bits of readonly mask to prevent sequential modification on certain configs.
    82  func (r *rpcConfig) LockConfig(bits int) {
    83  	r.readOnlyMask |= bits
    84  }
    85  
    86  // SetRPCTimeout implements MutableRPCConfig.
    87  func (r *rpcConfig) SetRPCTimeout(to time.Duration) error {
    88  	if !r.IsRPCTimeoutLocked() {
    89  		r.rpcTimeout = to
    90  		return nil
    91  	}
    92  	return kerrors.ErrNotSupported
    93  }
    94  
    95  // IsRPCTimeoutLocked implements the MutableRPCConfig interface.
    96  func (r *rpcConfig) IsRPCTimeoutLocked() bool {
    97  	return r.readOnlyMask&BitRPCTimeout != 0
    98  }
    99  
   100  // SetConnectTimeout implements MutableRPCConfig interface.
   101  func (r *rpcConfig) SetConnectTimeout(to time.Duration) error {
   102  	if !r.IsConnectTimeoutLocked() {
   103  		r.connectTimeout = to
   104  		return nil
   105  	}
   106  	return kerrors.ErrNotSupported
   107  }
   108  
   109  // IsConnectTimeoutLocked implements the MutableRPCConfig interface.
   110  func (r *rpcConfig) IsConnectTimeoutLocked() bool {
   111  	return r.readOnlyMask&BitConnectTimeout != 0
   112  }
   113  
   114  // SetReadWriteTimeout implements MutableRPCConfig interface.
   115  func (r *rpcConfig) SetReadWriteTimeout(to time.Duration) error {
   116  	if !r.IsReadWriteTimeoutLocked() {
   117  		r.readWriteTimeout = to
   118  		return nil
   119  	}
   120  	return kerrors.ErrNotSupported
   121  }
   122  
   123  // IsReadWriteTimeoutLocked implements the MutableRPCConfig interface.
   124  func (r *rpcConfig) IsReadWriteTimeoutLocked() bool {
   125  	return r.readOnlyMask&BitReadWriteTimeout != 0
   126  }
   127  
   128  // SetIOBufferSize implements MutableRPCConfig interface.
   129  func (r *rpcConfig) SetIOBufferSize(sz int) error {
   130  	if (r.readOnlyMask & BitIOBufferSize) == 0 {
   131  		r.ioBufferSize = sz
   132  		return nil
   133  	}
   134  	return kerrors.ErrNotSupported
   135  }
   136  
   137  // ImmutableView implements MutableRPCConfig interface.
   138  func (r *rpcConfig) ImmutableView() RPCConfig {
   139  	return r
   140  }
   141  
   142  // RPCTimeout implements RPCConfig interface.
   143  func (r *rpcConfig) RPCTimeout() time.Duration {
   144  	return r.rpcTimeout
   145  }
   146  
   147  // ConnectTimeout implements RPCConfig interface.
   148  func (r *rpcConfig) ConnectTimeout() time.Duration {
   149  	return r.connectTimeout
   150  }
   151  
   152  // ReadWriteTimeout implements RPCConfig interface.
   153  func (r *rpcConfig) ReadWriteTimeout() time.Duration {
   154  	return r.readWriteTimeout
   155  }
   156  
   157  // IOBufferSize implements RPCConfig interface.
   158  func (r *rpcConfig) IOBufferSize() int {
   159  	return r.ioBufferSize
   160  }
   161  
   162  // TransportProtocol implements RPCConfig interface. It is only useful for client.
   163  func (r *rpcConfig) TransportProtocol() transport.Protocol {
   164  	return r.transportProtocol
   165  }
   166  
   167  // SetTransportProtocol implements MutableRPCConfig interface.
   168  func (r *rpcConfig) SetTransportProtocol(tp transport.Protocol) error {
   169  	r.transportProtocol |= tp
   170  	return nil
   171  }
   172  
   173  func (r *rpcConfig) SetInteractionMode(mode InteractionMode) error {
   174  	r.interactionMode = mode
   175  	return nil
   176  }
   177  
   178  func (r *rpcConfig) InteractionMode() InteractionMode {
   179  	return r.interactionMode
   180  }
   181  
   182  func (r *rpcConfig) SetPayloadCodec(codec serviceinfo.PayloadCodec) {
   183  	r.payloadCodec = codec
   184  }
   185  
   186  func (r *rpcConfig) PayloadCodec() serviceinfo.PayloadCodec {
   187  	return r.payloadCodec
   188  }
   189  
   190  // Clone returns a copy of the current rpcConfig.
   191  func (r *rpcConfig) Clone() MutableRPCConfig {
   192  	r2 := rpcConfigPool.Get().(*rpcConfig)
   193  	*r2 = *r
   194  	return r2
   195  }
   196  
   197  func (r *rpcConfig) CopyFrom(from RPCConfig) {
   198  	f := from.(*rpcConfig)
   199  	*r = *f
   200  }
   201  
   202  func (r *rpcConfig) initialize() {
   203  	r.readOnlyMask = 0
   204  	r.rpcTimeout = defaultRPCTimeout
   205  	r.connectTimeout = defaultConnectTimeout
   206  	r.readWriteTimeout = defaultReadWriteTimeout
   207  	r.ioBufferSize = defaultBufferSize
   208  	r.transportProtocol = 0
   209  	r.interactionMode = defaultInteractionMode
   210  }
   211  
   212  // Recycle reuses the rpcConfig.
   213  func (r *rpcConfig) Recycle() {
   214  	r.initialize()
   215  	rpcConfigPool.Put(r)
   216  }
   217  
   218  // NewRPCConfig creates a default RPCConfig.
   219  func NewRPCConfig() RPCConfig {
   220  	r := rpcConfigPool.Get().(*rpcConfig)
   221  	return r
   222  }