github.com/cloudwego/kitex@v0.9.0/internal/server/option.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 server defines the Options of server
    18  package server
    19  
    20  import (
    21  	"context"
    22  	"os"
    23  	"os/signal"
    24  	"syscall"
    25  
    26  	"github.com/cloudwego/localsession/backup"
    27  
    28  	"github.com/cloudwego/kitex/internal/configutil"
    29  	"github.com/cloudwego/kitex/internal/stream"
    30  	"github.com/cloudwego/kitex/pkg/acl"
    31  	"github.com/cloudwego/kitex/pkg/diagnosis"
    32  	"github.com/cloudwego/kitex/pkg/endpoint"
    33  	"github.com/cloudwego/kitex/pkg/event"
    34  	"github.com/cloudwego/kitex/pkg/gofunc"
    35  	"github.com/cloudwego/kitex/pkg/limit"
    36  	"github.com/cloudwego/kitex/pkg/limiter"
    37  	"github.com/cloudwego/kitex/pkg/proxy"
    38  	"github.com/cloudwego/kitex/pkg/registry"
    39  	"github.com/cloudwego/kitex/pkg/remote"
    40  	"github.com/cloudwego/kitex/pkg/remote/codec/protobuf"
    41  	"github.com/cloudwego/kitex/pkg/remote/codec/thrift"
    42  	"github.com/cloudwego/kitex/pkg/remote/trans"
    43  	"github.com/cloudwego/kitex/pkg/rpcinfo"
    44  	"github.com/cloudwego/kitex/pkg/serviceinfo"
    45  	"github.com/cloudwego/kitex/pkg/stats"
    46  	"github.com/cloudwego/kitex/pkg/transmeta"
    47  	"github.com/cloudwego/kitex/pkg/utils"
    48  )
    49  
    50  func init() {
    51  	remote.PutPayloadCode(serviceinfo.Thrift, thrift.NewThriftCodec())
    52  	remote.PutPayloadCode(serviceinfo.Protobuf, protobuf.NewProtobufCodec())
    53  }
    54  
    55  // Option is the only way to config a server.
    56  type Option struct {
    57  	F func(o *Options, di *utils.Slice)
    58  }
    59  
    60  // Options is used to initialize the server.
    61  type Options struct {
    62  	Svr      *rpcinfo.EndpointBasicInfo
    63  	Configs  rpcinfo.RPCConfig
    64  	LockBits int
    65  	Once     *configutil.OptionOnce
    66  
    67  	MetaHandlers []remote.MetaHandler
    68  
    69  	RemoteOpt  *remote.ServerOption
    70  	ErrHandle  func(context.Context, error) error
    71  	ExitSignal func() <-chan error
    72  	Proxy      proxy.ReverseProxy
    73  
    74  	// Registry is used for service registry.
    75  	Registry registry.Registry
    76  	// RegistryInfo is used to in registry.
    77  	RegistryInfo *registry.Info
    78  
    79  	ACLRules []acl.RejectFunc
    80  	Limit    Limit
    81  
    82  	MWBs []endpoint.MiddlewareBuilder
    83  
    84  	Bus    event.Bus
    85  	Events event.Queue
    86  
    87  	SupportedTransportsFunc func(option remote.ServerOption) []string
    88  
    89  	// DebugInfo should only contain objects that are suitable for json serialization.
    90  	DebugInfo    utils.Slice
    91  	DebugService diagnosis.Service
    92  
    93  	// Observability
    94  	TracerCtl  *rpcinfo.TraceController
    95  	StatsLevel *stats.Level
    96  
    97  	BackupOpt backup.Options
    98  
    99  	Streaming stream.StreamingConfig
   100  
   101  	RefuseTrafficWithoutServiceName bool
   102  	EnableContextTimeout            bool
   103  }
   104  
   105  type Limit struct {
   106  	Limits        *limit.Option
   107  	LimitReporter limiter.LimitReporter
   108  	ConLimit      limiter.ConcurrencyLimiter
   109  	QPSLimit      limiter.RateLimiter
   110  
   111  	// QPSLimitPostDecode is true to indicate that the QPS limiter takes effect in
   112  	// the OnMessage callback, and false for the OnRead callback.
   113  	// Usually when the server is multiplexed, Kitex set it to True by default.
   114  	QPSLimitPostDecode bool
   115  }
   116  
   117  // NewOptions creates a default options.
   118  func NewOptions(opts []Option) *Options {
   119  	o := &Options{
   120  		Svr:          &rpcinfo.EndpointBasicInfo{},
   121  		Configs:      rpcinfo.NewRPCConfig(),
   122  		Once:         configutil.NewOptionOnce(),
   123  		MetaHandlers: []remote.MetaHandler{transmeta.MetainfoServerHandler},
   124  		RemoteOpt:    newServerRemoteOption(),
   125  		DebugService: diagnosis.NoopService,
   126  		ExitSignal:   DefaultSysExitSignal,
   127  
   128  		Bus:    event.NewEventBus(),
   129  		Events: event.NewQueue(event.MaxEventNum),
   130  
   131  		SupportedTransportsFunc: DefaultSupportedTransportsFunc,
   132  
   133  		TracerCtl: &rpcinfo.TraceController{},
   134  		Registry:  registry.NoopRegistry,
   135  	}
   136  	ApplyOptions(opts, o)
   137  	rpcinfo.AsMutableRPCConfig(o.Configs).LockConfig(o.LockBits)
   138  	if o.StatsLevel == nil {
   139  		level := stats.LevelDisabled
   140  		if o.TracerCtl.HasTracer() {
   141  			level = stats.LevelDetailed
   142  		}
   143  		o.StatsLevel = &level
   144  	}
   145  	return o
   146  }
   147  
   148  // ApplyOptions applies the given options.
   149  func ApplyOptions(opts []Option, o *Options) {
   150  	for _, op := range opts {
   151  		op.F(o, &o.DebugInfo)
   152  	}
   153  }
   154  
   155  func DefaultSysExitSignal() <-chan error {
   156  	errCh := make(chan error, 1)
   157  	gofunc.GoFunc(context.Background(), func() {
   158  		sig := SysExitSignal()
   159  		defer signal.Stop(sig)
   160  		<-sig
   161  		errCh <- nil
   162  	})
   163  	return errCh
   164  }
   165  
   166  func SysExitSignal() chan os.Signal {
   167  	signals := make(chan os.Signal, 1)
   168  	notifications := []os.Signal{syscall.SIGINT, syscall.SIGTERM}
   169  	if !signal.Ignored(syscall.SIGHUP) {
   170  		notifications = append(notifications, syscall.SIGHUP)
   171  	}
   172  	signal.Notify(signals, notifications...)
   173  	return signals
   174  }
   175  
   176  func DefaultSupportedTransportsFunc(option remote.ServerOption) []string {
   177  	if factory, ok := option.SvrHandlerFactory.(trans.MuxEnabledFlag); ok {
   178  		if factory.MuxEnabled() {
   179  			return []string{"ttheader_mux"}
   180  		} else {
   181  			return []string{"ttheader", "framed", "ttheader_framed", "grpc"}
   182  		}
   183  	}
   184  	return nil
   185  }