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 }