dubbo.apache.org/dubbo-go/v3@v3.1.1/config/graceful_shutdown_config.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package config 19 20 import ( 21 "time" 22 ) 23 24 import ( 25 "github.com/creasty/defaults" 26 27 "github.com/dubbogo/gost/log/logger" 28 29 "go.uber.org/atomic" 30 ) 31 32 import ( 33 "dubbo.apache.org/dubbo-go/v3/common/constant" 34 ) 35 36 const ( 37 defaultTimeout = 60 * time.Second 38 defaultStepTimeout = 3 * time.Second 39 defaultConsumerUpdateWaitTime = 3 * time.Second 40 defaultOfflineRequestWindowTimeout = 3 * time.Second 41 ) 42 43 // ShutdownConfig is used as configuration for graceful shutdown 44 type ShutdownConfig struct { 45 /* 46 * Total timeout. Even though we don't release all resources, 47 * the applicationConfig will shutdown if the costing time is over this configuration. The unit is ms. 48 * default value is 60 * 1000 ms = 1 minutes 49 * In general, it should be bigger than 3 * StepTimeout. 50 */ 51 Timeout string `default:"60s" yaml:"timeout" json:"timeout,omitempty" property:"timeout"` 52 /* 53 * the timeout on each step. You should evaluate the response time of request 54 * and the time that client noticed that server shutdown. 55 * For example, if your client will received the notification within 10s when you start to close server, 56 * and the 99.9% requests will return response in 2s, so the StepTimeout will be bigger than(10+2) * 1000ms, 57 * maybe (10 + 2*3) * 1000ms is a good choice. 58 */ 59 StepTimeout string `default:"3s" yaml:"step-timeout" json:"step.timeout,omitempty" property:"step.timeout"` 60 61 /* 62 * ConsumerUpdateWaitTime means when provider is shutting down, after the unregister, time to wait for client to 63 * update invokers. During this time, incoming invocation can be treated normally. 64 */ 65 ConsumerUpdateWaitTime string `default:"3s" yaml:"consumer-update-wait-time" json:"consumerUpdate.waitTIme,omitempty" property:"consumerUpdate.waitTIme"` 66 // when we try to shutdown the applicationConfig, we will reject the new requests. In most cases, you don't need to configure this. 67 RejectRequestHandler string `yaml:"reject-handler" json:"reject-handler,omitempty" property:"reject_handler"` 68 // internal listen kill signal,the default is true. 69 InternalSignal *bool `default:"true" yaml:"internal-signal" json:"internal.signal,omitempty" property:"internal.signal"` 70 // offline request window length 71 OfflineRequestWindowTimeout string `yaml:"offline-request-window-timeout" json:"offlineRequestWindowTimeout,omitempty" property:"offlineRequestWindowTimeout"` 72 // true -> new request will be rejected. 73 RejectRequest atomic.Bool 74 // active invocation 75 ConsumerActiveCount atomic.Int32 76 ProviderActiveCount atomic.Int32 77 78 // provider last received request timestamp 79 ProviderLastReceivedRequestTime atomic.Time 80 } 81 82 // Prefix dubbo.shutdown 83 func (config *ShutdownConfig) Prefix() string { 84 return constant.ShutdownConfigPrefix 85 } 86 87 func (config *ShutdownConfig) GetTimeout() time.Duration { 88 result, err := time.ParseDuration(config.Timeout) 89 if err != nil { 90 logger.Errorf("The Timeout configuration is invalid: %s, and we will use the default value: %s, err: %v", 91 config.Timeout, defaultTimeout.String(), err) 92 return defaultTimeout 93 } 94 return result 95 } 96 97 func (config *ShutdownConfig) GetStepTimeout() time.Duration { 98 result, err := time.ParseDuration(config.StepTimeout) 99 if err != nil { 100 logger.Errorf("The StepTimeout configuration is invalid: %s, and we will use the default value: %s, err: %v", 101 config.StepTimeout, defaultStepTimeout.String(), err) 102 return defaultStepTimeout 103 } 104 return result 105 } 106 107 func (config *ShutdownConfig) GetOfflineRequestWindowTimeout() time.Duration { 108 result, err := time.ParseDuration(config.OfflineRequestWindowTimeout) 109 if err != nil { 110 logger.Errorf("The OfflineRequestWindowTimeout configuration is invalid: %s, and we will use the default value: %s, err: %v", 111 config.OfflineRequestWindowTimeout, defaultOfflineRequestWindowTimeout.String(), err) 112 return defaultOfflineRequestWindowTimeout 113 } 114 return result 115 } 116 117 func (config *ShutdownConfig) GetConsumerUpdateWaitTime() time.Duration { 118 result, err := time.ParseDuration(config.ConsumerUpdateWaitTime) 119 if err != nil { 120 logger.Errorf("The ConsumerUpdateTimeout configuration is invalid: %s, and we will use the default value: %s, err: %v", 121 config.ConsumerActiveCount.Load(), defaultConsumerUpdateWaitTime.String(), err) 122 return defaultConsumerUpdateWaitTime 123 } 124 return result 125 } 126 127 func (config *ShutdownConfig) GetInternalSignal() bool { 128 if config.InternalSignal == nil { 129 return false 130 } 131 return *config.InternalSignal 132 } 133 134 func (config *ShutdownConfig) Init() error { 135 return defaults.Set(config) 136 } 137 138 type ShutdownConfigBuilder struct { 139 shutdownConfig *ShutdownConfig 140 } 141 142 func NewShutDownConfigBuilder() *ShutdownConfigBuilder { 143 return &ShutdownConfigBuilder{shutdownConfig: &ShutdownConfig{}} 144 } 145 146 func (scb *ShutdownConfigBuilder) SetTimeout(timeout string) *ShutdownConfigBuilder { 147 scb.shutdownConfig.Timeout = timeout 148 return scb 149 } 150 151 func (scb *ShutdownConfigBuilder) SetStepTimeout(stepTimeout string) *ShutdownConfigBuilder { 152 scb.shutdownConfig.StepTimeout = stepTimeout 153 return scb 154 } 155 156 func (scb *ShutdownConfigBuilder) SetRejectRequestHandler(rejectRequestHandler string) *ShutdownConfigBuilder { 157 scb.shutdownConfig.RejectRequestHandler = rejectRequestHandler 158 return scb 159 } 160 161 func (scb *ShutdownConfigBuilder) SetRejectRequest(rejectRequest bool) *ShutdownConfigBuilder { 162 scb.shutdownConfig.RejectRequest.Store(rejectRequest) 163 return scb 164 } 165 166 func (scb *ShutdownConfigBuilder) SetInternalSignal(internalSignal bool) *ShutdownConfigBuilder { 167 scb.shutdownConfig.InternalSignal = &internalSignal 168 return scb 169 } 170 171 func (scb *ShutdownConfigBuilder) Build() *ShutdownConfig { 172 defaults.MustSet(scb.shutdownConfig) 173 return scb.shutdownConfig 174 } 175 176 func (scb *ShutdownConfigBuilder) SetOfflineRequestWindowTimeout(offlineRequestWindowTimeout string) *ShutdownConfigBuilder { 177 scb.shutdownConfig.OfflineRequestWindowTimeout = offlineRequestWindowTimeout 178 return scb 179 }