This is an automated email from the ASF dual-hosted git repository.
alexstocks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 43c8bd03a Feat: Add Experimental Triple HTTP/3 Support (#2916)
43c8bd03a is described below
commit 43c8bd03adb00ba1adf978d7625c02a047a65929
Author: marsevilspirit <[email protected]>
AuthorDate: Sat Jul 12 19:59:45 2025 +0800
Feat: Add Experimental Triple HTTP/3 Support (#2916)
* start triple http3 server successfully!
* add http3 config for triple protocol
* rename URL to url
* fix v1.33.0 of google.golang.org/protobuf Fails to Compile
ref: https://github.com/protocolbuffers/protobuf/issues/16163
* triple http3 client start successfully!
* add some comments
* update triple server run logic
* optimize http type
* make triple http3 support keepalive option
* add http2 keepalive config with tls
* rename genKeepAliveOptions
* add some todo
* opitmize tlsConf params
* fix http protocol bug
* rename callProtocol
* add some comments about http3 config
* make panic when triple http3 server's TLS config is nil.
* fix typo
* opitmize config code
* add experimental warning for http3 api
* add some todo
* support instance and yaml start with http3
* enable http3 gracefulstop
* opitmize callprotocol usage
* rename ProtocolClientConfig to ClientProtocolConfig
* replace panic with return error
* optimize logger output
* optimize parser error
* add some comments
* add config unit tests
* Use a WaitGroup to manage the concurrent shutdown of goroutines
effectively.
* fix typo and add config unit test
* use switch to handle error
---
client/options.go | 2 +-
common/constant/key.go | 2 +-
compat.go | 157 +++++++++++++++++----
.../client_protocol_config.go | 30 +---
config/{triple_config.go => http3_config.go} | 20 ++-
config/reference_config.go | 44 +++---
config/triple_config.go | 12 +-
..._client_config.go => client_protocol_config.go} | 16 +--
global/config_test.go | 21 +++
.../{protocol_client_config.go => http3_config.go} | 42 +++---
global/reference_config.go | 16 ++-
global/triple_config.go | 33 ++++-
go.mod | 34 +++--
go.sum | 74 +++++-----
protocol/options.go | 4 +-
protocol/triple/client.go | 86 ++++++++---
protocol/triple/options.go | 13 ++
protocol/triple/server.go | 70 +++++----
protocol/triple/triple_protocol/server.go | 156 ++++++++++++++++++--
19 files changed, 592 insertions(+), 240 deletions(-)
diff --git a/client/options.go b/client/options.go
index 051558043..9d0b47991 100644
--- a/client/options.go
+++ b/client/options.go
@@ -856,7 +856,7 @@ func WithClientProtocol(opts ...protocol.ClientOption)
ClientOption {
return func(srvOpts *ClientOptions) {
if srvOpts.overallReference.ProtocolClientConfig == nil {
- srvOpts.overallReference.ProtocolClientConfig =
new(global.ProtocolClientConfig)
+ srvOpts.overallReference.ProtocolClientConfig =
new(global.ClientProtocolConfig)
}
srvOpts.overallReference.ProtocolClientConfig =
proOpts.ProtocolClient
}
diff --git a/common/constant/key.go b/common/constant/key.go
index 43ace78c7..fdc9cc576 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -158,9 +158,9 @@ const (
CallClientStream = "client-stream"
CallServerStream = "server-stream"
CallBidiStream = "bidi-stream"
- CallHTTPTypeKey = "call-http-type"
CallHTTP = "http"
CallHTTP2 = "http2"
+ CallHTTP3 = "http3"
ServiceInfoKey = "service-info"
RpcServiceKey = "rpc-service"
ClientInfoKey = "client-info"
diff --git a/compat.go b/compat.go
index 5c622c369..a46dbf851 100644
--- a/compat.go
+++ b/compat.go
@@ -99,10 +99,22 @@ func compatTripleConfig(c *global.TripleConfig)
*config.TripleConfig {
return nil
}
return &config.TripleConfig{
- KeepAliveInterval: c.KeepAliveInterval,
- KeepAliveTimeout: c.KeepAliveTimeout,
MaxServerSendMsgSize: c.MaxServerSendMsgSize,
MaxServerRecvMsgSize: c.MaxServerRecvMsgSize,
+ Http3: compatHttp3Config(c.Http3),
+
+ KeepAliveInterval: c.KeepAliveInterval,
+ KeepAliveTimeout: c.KeepAliveTimeout,
+ }
+}
+
+// just for compat
+func compatHttp3Config(c *global.Http3Config) *config.Http3Config {
+ if c == nil {
+ return nil
+ }
+ return &config.Http3Config{
+ Enable: c.Enable,
}
}
@@ -276,6 +288,73 @@ func compatConsumerConfig(c *global.ConsumerConfig)
*config.ConsumerConfig {
FilterConf: c.FilterConf,
MaxWaitTimeForServiceDiscovery:
c.MaxWaitTimeForServiceDiscovery,
MeshEnabled: c.MeshEnabled,
+ References: compatReferences(c.References),
+ }
+}
+
+func compatReferences(c map[string]*global.ReferenceConfig)
map[string]*config.ReferenceConfig {
+ refs := make(map[string]*config.ReferenceConfig, len(c))
+ for name, ref := range c {
+ refs[name] = &config.ReferenceConfig{
+ InterfaceName: ref.InterfaceName,
+ Check: ref.Check,
+ URL: ref.URL,
+ Filter: ref.Filter,
+ Protocol: ref.Protocol,
+ RegistryIDs: ref.RegistryIDs,
+ Cluster: ref.Cluster,
+ Loadbalance: ref.Loadbalance,
+ Retries: ref.Retries,
+ Group: ref.Group,
+ Version: ref.Version,
+ Serialization: ref.Serialization,
+ ProvidedBy: ref.ProvidedBy,
+ MethodsConfig: compatMethod(ref.MethodsConfig),
+ ProtocolClientConfig:
compatProtocolClientConfig(ref.ProtocolClientConfig),
+ Async: ref.Async,
+ Params: ref.Params,
+ Generic: ref.Generic,
+ Sticky: ref.Sticky,
+ RequestTimeout: ref.RequestTimeout,
+ ForceTag: ref.ForceTag,
+ TracingKey: ref.TracingKey,
+ MeshProviderPort: ref.MeshProviderPort,
+ }
+ }
+ return refs
+}
+
+// TODO: merge compatGlobalMethod() and compatGlobalMethodConfig
+func compatMethod(m []*global.MethodConfig) []*config.MethodConfig {
+ methods := make([]*config.MethodConfig, 0, len(m))
+ for _, method := range m {
+ methods = append(methods, &config.MethodConfig{
+ InterfaceId: method.InterfaceId,
+ InterfaceName: method.InterfaceName,
+ Name: method.Name,
+ Retries: method.Retries,
+ LoadBalance: method.LoadBalance,
+ Weight: method.Weight,
+ TpsLimitInterval: method.TpsLimitInterval,
+ TpsLimitRate: method.TpsLimitRate,
+ TpsLimitStrategy: method.TpsLimitStrategy,
+ ExecuteLimit: method.ExecuteLimit,
+ ExecuteLimitRejectedHandler:
method.ExecuteLimitRejectedHandler,
+ Sticky: method.Sticky,
+ RequestTimeout: method.RequestTimeout,
+ })
+ }
+ return methods
+}
+
+// just for compat
+func compatProtocolClientConfig(c *global.ClientProtocolConfig)
*config.ClientProtocolConfig {
+ if c == nil {
+ return nil
+ }
+ return &config.ClientProtocolConfig{
+ Name: c.Name,
+ TripleConfig: compatTripleConfig(c.TripleConfig),
}
}
@@ -422,6 +501,7 @@ func compatInstanceOptions(cr *config.RootConfig, rc
*InstanceOptions) {
if cr == nil {
return
}
+
proCompat := make(map[string]*global.ProtocolConfig)
for k, v := range cr.Protocols {
proCompat[k] = compatGlobalProtocolConfig(v)
@@ -470,13 +550,25 @@ func compatGlobalTripleConfig(c *config.TripleConfig)
*global.TripleConfig {
return nil
}
return &global.TripleConfig{
- KeepAliveInterval: c.KeepAliveInterval,
- KeepAliveTimeout: c.KeepAliveTimeout,
+ KeepAliveInterval: c.KeepAliveInterval,
+ KeepAliveTimeout: c.KeepAliveTimeout,
+ Http3: compatGlobalHttp3Config(c.Http3),
+
MaxServerSendMsgSize: c.MaxServerSendMsgSize,
MaxServerRecvMsgSize: c.MaxServerRecvMsgSize,
}
}
+// just for compat
+func compatGlobalHttp3Config(c *config.Http3Config) *global.Http3Config {
+ if c == nil {
+ return nil
+ }
+ return &global.Http3Config{
+ Enable: c.Enable,
+ }
+}
+
func compatGlobalRegistryConfig(c *config.RegistryConfig)
*global.RegistryConfig {
if c == nil {
return nil
@@ -674,33 +766,35 @@ func compatGlobalReferences(c
map[string]*config.ReferenceConfig) map[string]*gl
refs := make(map[string]*global.ReferenceConfig, len(c))
for name, ref := range c {
refs[name] = &global.ReferenceConfig{
- InterfaceName: ref.InterfaceName,
- Check: ref.Check,
- URL: ref.URL,
- Filter: ref.Filter,
- Protocol: ref.Protocol,
- RegistryIDs: ref.RegistryIDs,
- Cluster: ref.Cluster,
- Loadbalance: ref.Loadbalance,
- Retries: ref.Retries,
- Group: ref.Group,
- Version: ref.Version,
- Serialization: ref.Serialization,
- ProvidedBy: ref.ProvidedBy,
- MethodsConfig: compatGlobalMethod(ref.Methods),
- Async: ref.Async,
- Params: ref.Params,
- Generic: ref.Generic,
- Sticky: ref.Sticky,
- RequestTimeout: ref.RequestTimeout,
- ForceTag: ref.ForceTag,
- TracingKey: ref.TracingKey,
- MeshProviderPort: ref.MeshProviderPort,
+ InterfaceName: ref.InterfaceName,
+ Check: ref.Check,
+ URL: ref.URL,
+ Filter: ref.Filter,
+ Protocol: ref.Protocol,
+ RegistryIDs: ref.RegistryIDs,
+ Cluster: ref.Cluster,
+ Loadbalance: ref.Loadbalance,
+ Retries: ref.Retries,
+ Group: ref.Group,
+ Version: ref.Version,
+ Serialization: ref.Serialization,
+ ProvidedBy: ref.ProvidedBy,
+ MethodsConfig:
compatGlobalMethod(ref.MethodsConfig),
+ ProtocolClientConfig:
compatGlobalProtocolClientConfig(ref.ProtocolClientConfig),
+ Async: ref.Async,
+ Params: ref.Params,
+ Generic: ref.Generic,
+ Sticky: ref.Sticky,
+ RequestTimeout: ref.RequestTimeout,
+ ForceTag: ref.ForceTag,
+ TracingKey: ref.TracingKey,
+ MeshProviderPort: ref.MeshProviderPort,
}
}
return refs
}
+// TODO: merge compatGlobalMethod() and compatGlobalMethodConfig
func compatGlobalMethod(m []*config.MethodConfig) []*global.MethodConfig {
methods := make([]*global.MethodConfig, 0, len(m))
for _, method := range m {
@@ -723,6 +817,17 @@ func compatGlobalMethod(m []*config.MethodConfig)
[]*global.MethodConfig {
return methods
}
+// just for compat
+func compatGlobalProtocolClientConfig(c *config.ClientProtocolConfig)
*global.ClientProtocolConfig {
+ if c == nil {
+ return nil
+ }
+ return &global.ClientProtocolConfig{
+ Name: c.Name,
+ TripleConfig: compatGlobalTripleConfig(c.TripleConfig),
+ }
+}
+
func compatGlobalMetricConfig(c *config.MetricsConfig) *global.MetricsConfig {
if c == nil {
return nil
diff --git a/global/protocol_client_config.go b/config/client_protocol_config.go
similarity index 61%
copy from global/protocol_client_config.go
copy to config/client_protocol_config.go
index 6d9f1a594..e801a0f78 100644
--- a/global/protocol_client_config.go
+++ b/config/client_protocol_config.go
@@ -15,36 +15,12 @@
* limitations under the License.
*/
-package global
+package config
-import (
- "dubbo.apache.org/dubbo-go/v3/common/constant"
-)
-
-// TODO: find a better name replace ProtocolClientConfig
-type ProtocolClientConfig struct {
+// ClientProtocolConfig represents the config of client's protocol
+type ClientProtocolConfig struct {
// TODO: maybe we could use this field
Name string `yaml:"name" json:"name,omitempty" property:"name"`
TripleConfig *TripleConfig `yaml:"triple" json:"triple,omitempty"
property:"triple"`
}
-
-// DefaultProtocolConfig returns a default ProtocolConfig instance.
-func DefaultProtocolClientConfig() *ProtocolClientConfig {
- return &ProtocolClientConfig{
- Name: constant.TriProtocol,
- TripleConfig: DefaultTripleConfig(),
- }
-}
-
-// Clone a new ProtocolConfig
-func (c *ProtocolClientConfig) Clone() *ProtocolClientConfig {
- if c == nil {
- return nil
- }
-
- return &ProtocolClientConfig{
- Name: c.Name,
- TripleConfig: c.TripleConfig.Clone(),
- }
-}
diff --git a/config/triple_config.go b/config/http3_config.go
similarity index 53%
copy from config/triple_config.go
copy to config/http3_config.go
index 2fbd99909..bede6e551 100644
--- a/config/triple_config.go
+++ b/config/http3_config.go
@@ -17,12 +17,18 @@
package config
-type TripleConfig struct {
- KeepAliveInterval string `yaml:"keep-alive-interval"
json:"keep-alive-interval,omitempty" property:"keep-alive-interval"`
- KeepAliveTimeout string `yaml:"keep-alive-timeout"
json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"`
+// Http3Config represents the config of http3
+type Http3Config struct {
+ // Whether to enable HTTP/3 support.
+ // The default value is false.
+ Enable bool `yaml:"enable" json:"enable,omitempty"`
+ // TODO: add more params about http3
- // MaxServerSendMsgSize max size of server send message,
1mb=1000kb=1000000b 1mib=1024kb=1048576b.
- // more detail to see
https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants
- MaxServerSendMsgSize string `yaml:"max-server-send-msg-size"
json:"max-server-send-msg-size,omitempty"` // MaxServerRecvMsgSize max size of
server receive message
- MaxServerRecvMsgSize string `yaml:"max-server-recv-msg-size"
json:"max-server-recv-msg-size,omitempty"`
+ // TODO: negotiation implementation
+ // ref:
https://quic-go.net/docs/http3/server/#advertising-http3-via-alt-svc
+ //
+ // Whether to enable HTTP/3 negotiation.
+ // If set to false, HTTP/2 alt-svc negotiation will be skipped,
+ // enabling HTTP/3 but disabling HTTP/2 on the consumer side.
+ // negotiation bool
}
diff --git a/config/reference_config.go b/config/reference_config.go
index 88bb1b627..9657f931d 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -52,21 +52,25 @@ type ReferenceConfig struct {
urls []*common.URL
rootConfig *RootConfig
- id string
- InterfaceName string `yaml:"interface"
json:"interface,omitempty" property:"interface"`
- Check *bool `yaml:"check"
json:"check,omitempty" property:"check"`
- URL string `yaml:"url" json:"url,omitempty"
property:"url"`
- Filter string `yaml:"filter"
json:"filter,omitempty" property:"filter"`
- Protocol string `yaml:"protocol"
json:"protocol,omitempty" property:"protocol"`
- RegistryIDs []string `yaml:"registry-ids"
json:"registry-ids,omitempty" property:"registry-ids"`
- Cluster string `yaml:"cluster"
json:"cluster,omitempty" property:"cluster"`
- Loadbalance string `yaml:"loadbalance"
json:"loadbalance,omitempty" property:"loadbalance"`
- Retries string `yaml:"retries"
json:"retries,omitempty" property:"retries"`
- Group string `yaml:"group"
json:"group,omitempty" property:"group"`
- Version string `yaml:"version"
json:"version,omitempty" property:"version"`
- Serialization string `yaml:"serialization"
json:"serialization" property:"serialization"`
- ProvidedBy string `yaml:"provided_by"
json:"provided_by,omitempty" property:"provided_by"`
- Methods []*MethodConfig `yaml:"methods"
json:"methods,omitempty" property:"methods"`
+ id string
+ InterfaceName string `yaml:"interface" json:"interface,omitempty"
property:"interface"`
+ Check *bool `yaml:"check" json:"check,omitempty"
property:"check"`
+ URL string `yaml:"url" json:"url,omitempty" property:"url"`
+ Filter string `yaml:"filter" json:"filter,omitempty"
property:"filter"`
+ Protocol string `yaml:"protocol" json:"protocol,omitempty"
property:"protocol"`
+ RegistryIDs []string `yaml:"registry-ids"
json:"registry-ids,omitempty" property:"registry-ids"`
+ Cluster string `yaml:"cluster" json:"cluster,omitempty"
property:"cluster"`
+ Loadbalance string `yaml:"loadbalance"
json:"loadbalance,omitempty" property:"loadbalance"`
+ Retries string `yaml:"retries" json:"retries,omitempty"
property:"retries"`
+ Group string `yaml:"group" json:"group,omitempty"
property:"group"`
+ Version string `yaml:"version" json:"version,omitempty"
property:"version"`
+ Serialization string `yaml:"serialization" json:"serialization"
property:"serialization"`
+ ProvidedBy string `yaml:"provided_by"
json:"provided_by,omitempty" property:"provided_by"`
+
+ MethodsConfig []*MethodConfig `yaml:"methods" json:"methods,omitempty"
property:"methods"`
+ // TODO: rename protocol_config to protocol when publish 4.0.0.
+ ProtocolClientConfig *ClientProtocolConfig `yaml:"protocol_config"
json:"protocol_config,omitempty" property:"protocol_config"`
+
Async bool `yaml:"async"
json:"async,omitempty" property:"async"`
Params map[string]string `yaml:"params"
json:"params,omitempty" property:"params"`
Generic string `yaml:"generic"
json:"generic,omitempty" property:"generic"`
@@ -84,7 +88,7 @@ func (rc *ReferenceConfig) Prefix() string {
}
func (rc *ReferenceConfig) Init(root *RootConfig) error {
- for _, method := range rc.Methods {
+ for _, method := range rc.MethodsConfig {
if err := method.Init(); err != nil {
return err
}
@@ -364,7 +368,7 @@ func (rc *ReferenceConfig) getURLMap() url.Values {
}
urlMap.Set(constant.ReferenceFilterKey, mergeValue(rc.Filter, "",
defaultReferenceFilter))
- for _, v := range rc.Methods {
+ for _, v := range rc.MethodsConfig {
urlMap.Set("methods."+v.Name+"."+constant.LoadbalanceKey,
v.LoadBalance)
urlMap.Set("methods."+v.Name+"."+constant.RetriesKey, v.Retries)
urlMap.Set("methods."+v.Name+"."+constant.StickyKey,
strconv.FormatBool(v.Sticky))
@@ -402,7 +406,7 @@ func (rc *ReferenceConfig) postProcessConfig(url
*common.URL) {
// newEmptyReferenceConfig returns empty ReferenceConfig
func newEmptyReferenceConfig() *ReferenceConfig {
newReferenceConfig := &ReferenceConfig{}
- newReferenceConfig.Methods = make([]*MethodConfig, 0, 8)
+ newReferenceConfig.MethodsConfig = make([]*MethodConfig, 0, 8)
newReferenceConfig.Params = make(map[string]string, 8)
return newReferenceConfig
}
@@ -485,12 +489,12 @@ func (pcb *ReferenceConfigBuilder)
SetProvidedBy(providedBy string) *ReferenceCo
}
func (pcb *ReferenceConfigBuilder) SetMethodConfig(methodConfigs
[]*MethodConfig) *ReferenceConfigBuilder {
- pcb.referenceConfig.Methods = methodConfigs
+ pcb.referenceConfig.MethodsConfig = methodConfigs
return pcb
}
func (pcb *ReferenceConfigBuilder) AddMethodConfig(methodConfig *MethodConfig)
*ReferenceConfigBuilder {
- pcb.referenceConfig.Methods = append(pcb.referenceConfig.Methods,
methodConfig)
+ pcb.referenceConfig.MethodsConfig =
append(pcb.referenceConfig.MethodsConfig, methodConfig)
return pcb
}
diff --git a/config/triple_config.go b/config/triple_config.go
index 2fbd99909..5a0561112 100644
--- a/config/triple_config.go
+++ b/config/triple_config.go
@@ -17,12 +17,16 @@
package config
+// TripleConfig represents the config of triple protocol
type TripleConfig struct {
- KeepAliveInterval string `yaml:"keep-alive-interval"
json:"keep-alive-interval,omitempty" property:"keep-alive-interval"`
- KeepAliveTimeout string `yaml:"keep-alive-timeout"
json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"`
-
// MaxServerSendMsgSize max size of server send message,
1mb=1000kb=1000000b 1mib=1024kb=1048576b.
// more detail to see
https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants
- MaxServerSendMsgSize string `yaml:"max-server-send-msg-size"
json:"max-server-send-msg-size,omitempty"` // MaxServerRecvMsgSize max size of
server receive message
+ MaxServerSendMsgSize string `yaml:"max-server-send-msg-size"
json:"max-server-send-msg-size,omitempty"`
+ // MaxServerRecvMsgSize max size of server receive message
MaxServerRecvMsgSize string `yaml:"max-server-recv-msg-size"
json:"max-server-recv-msg-size,omitempty"`
+
+ Http3 *Http3Config `yaml:"http3" json:"http3,omitempty"
property:"http3"`
+
+ KeepAliveInterval string `yaml:"keep-alive-interval"
json:"keep-alive-interval,omitempty" property:"keep-alive-interval"`
+ KeepAliveTimeout string `yaml:"keep-alive-timeout"
json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"`
}
diff --git a/global/protocol_client_config.go b/global/client_protocol_config.go
similarity index 75%
copy from global/protocol_client_config.go
copy to global/client_protocol_config.go
index 6d9f1a594..4856d86c0 100644
--- a/global/protocol_client_config.go
+++ b/global/client_protocol_config.go
@@ -21,29 +21,29 @@ import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
)
-// TODO: find a better name replace ProtocolClientConfig
-type ProtocolClientConfig struct {
+// ClientProtocolConfig represents the config of client's protocol
+type ClientProtocolConfig struct {
// TODO: maybe we could use this field
Name string `yaml:"name" json:"name,omitempty" property:"name"`
TripleConfig *TripleConfig `yaml:"triple" json:"triple,omitempty"
property:"triple"`
}
-// DefaultProtocolConfig returns a default ProtocolConfig instance.
-func DefaultProtocolClientConfig() *ProtocolClientConfig {
- return &ProtocolClientConfig{
+// DefaultClientProtocolConfig returns a default ClientProtocolConfig instance.
+func DefaultClientProtocolConfig() *ClientProtocolConfig {
+ return &ClientProtocolConfig{
Name: constant.TriProtocol,
TripleConfig: DefaultTripleConfig(),
}
}
-// Clone a new ProtocolConfig
-func (c *ProtocolClientConfig) Clone() *ProtocolClientConfig {
+// Clone a new ClientProtocolConfig
+func (c *ClientProtocolConfig) Clone() *ClientProtocolConfig {
if c == nil {
return nil
}
- return &ProtocolClientConfig{
+ return &ClientProtocolConfig{
Name: c.Name,
TripleConfig: c.TripleConfig.Clone(),
}
diff --git a/global/config_test.go b/global/config_test.go
index 4e7727ae7..c436a7d75 100644
--- a/global/config_test.go
+++ b/global/config_test.go
@@ -130,6 +130,13 @@ func TestCloneConfig(t *testing.T) {
CheckCompleteInequality(t, c, clone)
})
+ t.Run("ClientProtocolConfig", func(t *testing.T) {
+ c := DefaultClientProtocolConfig()
+ InitCheckCompleteInequality(t, c)
+ clone := c.Clone()
+ CheckCompleteInequality(t, c, clone)
+ })
+
t.Run("ProviderConfig", func(t *testing.T) {
c := DefaultProviderConfig()
InitCheckCompleteInequality(t, c)
@@ -171,6 +178,20 @@ func TestCloneConfig(t *testing.T) {
clone := c.Clone()
CheckCompleteInequality(t, c, clone)
})
+
+ t.Run("TripleConfig", func(t *testing.T) {
+ c := DefaultTripleConfig()
+ InitCheckCompleteInequality(t, c)
+ clone := c.Clone()
+ CheckCompleteInequality(t, c, clone)
+ })
+
+ t.Run("Http3Config", func(t *testing.T) {
+ c := DefaultHttp3Config()
+ InitCheckCompleteInequality(t, c)
+ clone := c.Clone()
+ CheckCompleteInequality(t, c, clone)
+ })
}
func InitCheckCompleteInequality(t *testing.T, origin any) {
diff --git a/global/protocol_client_config.go b/global/http3_config.go
similarity index 51%
rename from global/protocol_client_config.go
rename to global/http3_config.go
index 6d9f1a594..e191dfbca 100644
--- a/global/protocol_client_config.go
+++ b/global/http3_config.go
@@ -17,34 +17,34 @@
package global
-import (
- "dubbo.apache.org/dubbo-go/v3/common/constant"
-)
+// Http3Config represents the config of http3
+type Http3Config struct {
+ // Whether to enable HTTP/3 support.
+ // The default value is false.
+ Enable bool `yaml:"enable" json:"enable,omitempty"`
+ // TODO: add more params about http3
-// TODO: find a better name replace ProtocolClientConfig
-type ProtocolClientConfig struct {
- // TODO: maybe we could use this field
- Name string `yaml:"name" json:"name,omitempty" property:"name"`
-
- TripleConfig *TripleConfig `yaml:"triple" json:"triple,omitempty"
property:"triple"`
+ // TODO: negotiation implementation
+ // ref:
https://quic-go.net/docs/http3/server/#advertising-http3-via-alt-svc
+ //
+ // Whether to enable HTTP/3 negotiation.
+ // If set to false, HTTP/2 alt-svc negotiation will be skipped,
+ // enabling HTTP/3 but disabling HTTP/2 on the consumer side.
+ // negotiation bool
}
-// DefaultProtocolConfig returns a default ProtocolConfig instance.
-func DefaultProtocolClientConfig() *ProtocolClientConfig {
- return &ProtocolClientConfig{
- Name: constant.TriProtocol,
- TripleConfig: DefaultTripleConfig(),
- }
+// DefaultHttp3Config returns a default Http3Config instance.
+func DefaultHttp3Config() *Http3Config {
+ return &Http3Config{}
}
-// Clone a new ProtocolConfig
-func (c *ProtocolClientConfig) Clone() *ProtocolClientConfig {
- if c == nil {
+// Clone a new Http3Config
+func (t *Http3Config) Clone() *Http3Config {
+ if t == nil {
return nil
}
- return &ProtocolClientConfig{
- Name: c.Name,
- TripleConfig: c.TripleConfig.Clone(),
+ return &Http3Config{
+ Enable: t.Enable,
}
}
diff --git a/global/reference_config.go b/global/reference_config.go
index 013068a94..d7db62751 100644
--- a/global/reference_config.go
+++ b/global/reference_config.go
@@ -46,8 +46,9 @@ type ReferenceConfig struct {
MeshProviderPort int `yaml:"mesh-provider-port"
json:"mesh-provider-port,omitempty" property:"mesh-provider-port"`
// config
- MethodsConfig []*MethodConfig `yaml:"methods"
json:"methods,omitempty" property:"methods"`
- ProtocolClientConfig *ProtocolClientConfig `yaml:"protocol-config"
json:"protocol-config,omitempty" property:"protocol-config"`
+ MethodsConfig []*MethodConfig `yaml:"methods" json:"methods,omitempty"
property:"methods"`
+ // TODO: rename protocol_config to protocol when publish 4.0.0.
+ ProtocolClientConfig *ClientProtocolConfig `yaml:"protocol_config"
json:"protocol_config,omitempty" property:"protocol_config"`
// TODO: Deprecated:use TripleConfig
// remove KeepAliveInterval and KeepAliveInterval in version 4.0.0
@@ -64,7 +65,7 @@ func DefaultReferenceConfig() *ReferenceConfig {
// use Triple protocol by default
//Protocol: "tri",
MethodsConfig: make([]*MethodConfig, 0, 8),
- ProtocolClientConfig: DefaultProtocolClientConfig(),
+ ProtocolClientConfig: DefaultClientProtocolConfig(),
//Params: make(map[string]string, 8),
}
}
@@ -141,6 +142,9 @@ func (c *ReferenceConfig) GetOptions() []ReferenceOption {
if c.KeepAliveTimeout != "" {
refOpts = append(refOpts,
WithReference_KeepAliveTimeout(c.KeepAliveTimeout))
}
+ if c.ProtocolClientConfig != nil {
+ refOpts = append(refOpts,
WithReference_ProtocolClientConfig(c.ProtocolClientConfig))
+ }
return refOpts
}
@@ -343,3 +347,9 @@ func WithReference_KeepAliveTimeout(timeout string)
ReferenceOption {
cfg.KeepAliveTimeout = timeout
}
}
+
+func WithReference_ProtocolClientConfig(protocolClientConfig
*ClientProtocolConfig) ReferenceOption {
+ return func(cfg *ReferenceConfig) {
+ cfg.ProtocolClientConfig = protocolClientConfig.Clone()
+ }
+}
diff --git a/global/triple_config.go b/global/triple_config.go
index a5fcf7a86..83b57c63d 100644
--- a/global/triple_config.go
+++ b/global/triple_config.go
@@ -17,19 +17,36 @@
package global
-// TODO: Should the server and client configurations be separated?
+// TODO: Find an ideal way to separate the triple config of server and client.
+
+// TripleConfig represents the config of triple protocol
type TripleConfig struct {
- KeepAliveInterval string `yaml:"keep-alive-interval"
json:"keep-alive-interval,omitempty" property:"keep-alive-interval"`
- KeepAliveTimeout string `yaml:"keep-alive-timeout"
json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"`
+ //
+ // for server
+ //
// MaxServerSendMsgSize max size of server send message,
1mb=1000kb=1000000b 1mib=1024kb=1048576b.
// more detail to see
https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants
- MaxServerSendMsgSize string `yaml:"max-server-send-msg-size"
json:"max-server-send-msg-size,omitempty"` // MaxServerRecvMsgSize max size of
server receive message
+ MaxServerSendMsgSize string `yaml:"max-server-send-msg-size"
json:"max-server-send-msg-size,omitempty"`
+ // MaxServerRecvMsgSize max size of server receive message
MaxServerRecvMsgSize string `yaml:"max-server-recv-msg-size"
json:"max-server-recv-msg-size,omitempty"`
+
+ // the config of http3 transport
+ Http3 *Http3Config `yaml:"http3" json:"http3,omitempty"`
+
+ //
+ // for client
+ //
+
+ KeepAliveInterval string `yaml:"keep-alive-interval"
json:"keep-alive-interval,omitempty" property:"keep-alive-interval"`
+ KeepAliveTimeout string `yaml:"keep-alive-timeout"
json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"`
}
+// DefaultTripleConfig returns a default TripleConfig instance.
func DefaultTripleConfig() *TripleConfig {
- return &TripleConfig{}
+ return &TripleConfig{
+ Http3: DefaultHttp3Config(),
+ }
}
// Clone a new TripleConfig
@@ -39,9 +56,11 @@ func (t *TripleConfig) Clone() *TripleConfig {
}
return &TripleConfig{
- KeepAliveInterval: t.KeepAliveInterval,
- KeepAliveTimeout: t.KeepAliveTimeout,
MaxServerSendMsgSize: t.MaxServerSendMsgSize,
MaxServerRecvMsgSize: t.MaxServerRecvMsgSize,
+ Http3: t.Http3.Clone(),
+
+ KeepAliveInterval: t.KeepAliveInterval,
+ KeepAliveTimeout: t.KeepAliveTimeout,
}
}
diff --git a/go.mod b/go.mod
index 54b05cc46..28e64ceaa 100644
--- a/go.mod
+++ b/go.mod
@@ -23,7 +23,7 @@ require (
github.com/go-playground/validator/v10 v10.12.0
github.com/go-resty/resty/v2 v2.7.0
github.com/golang/mock v1.6.0
- github.com/golang/protobuf v1.5.3
+ github.com/golang/protobuf v1.5.4
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.3.1
github.com/grpc-ecosystem/grpc-opentracing
v0.0.0-20180507213350-8e809c8a8645
@@ -42,10 +42,11 @@ require (
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
github.com/polarismesh/polaris-go v1.3.0
- github.com/prometheus/client_golang v1.13.0
- github.com/prometheus/common v0.37.0
+ github.com/prometheus/client_golang v1.19.1
+ github.com/prometheus/common v0.48.0
+ github.com/quic-go/quic-go v0.52.0
github.com/sirupsen/logrus v1.8.1
- github.com/stretchr/testify v1.8.4
+ github.com/stretchr/testify v1.9.0
github.com/ugorji/go/codec v1.2.6
go.etcd.io/etcd/api/v3 v3.5.7
go.etcd.io/etcd/client/v3 v3.5.7
@@ -61,9 +62,9 @@ require (
go.opentelemetry.io/otel/trace v1.21.0
go.uber.org/atomic v1.10.0
go.uber.org/zap v1.21.0
- golang.org/x/net v0.23.0
+ golang.org/x/net v0.28.0
google.golang.org/grpc v1.59.0
- google.golang.org/protobuf v1.31.0
+ google.golang.org/protobuf v1.33.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v2 v2.4.0
)
@@ -85,6 +86,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 //
indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
@@ -100,19 +102,20 @@ require (
github.com/leodido/go-urn v1.2.2 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 //
indirect
github.com/mattn/go-isatty v0.0.16 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
+ github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/openzipkin/zipkin-go v0.4.2 // indirect
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c //
indirect
- github.com/prometheus/client_model v0.3.0 // indirect
- github.com/prometheus/procfs v0.8.0 // indirect
+ github.com/prometheus/client_model v0.5.0 // indirect
+ github.com/prometheus/procfs v0.12.0 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
github.com/shirou/gopsutil/v3 v3.22.2 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
@@ -120,7 +123,7 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.8.1 // indirect
- github.com/stretchr/objx v0.5.0 // indirect
+ github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
@@ -130,12 +133,15 @@ require (
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
+ go.uber.org/mock v0.5.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
- golang.org/x/crypto v0.21.0 // indirect
- golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.18.0 // indirect
- golang.org/x/text v0.14.0 // indirect
+ golang.org/x/crypto v0.26.0 // indirect
+ golang.org/x/mod v0.18.0 // indirect
+ golang.org/x/sync v0.8.0 // indirect
+ golang.org/x/sys v0.23.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
+ golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d //
indirect
google.golang.org/genproto/googleapis/api
v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc
v0.0.0-20230822172742-b8732ec3820d // indirect
diff --git a/go.sum b/go.sum
index 950592ab1..1e3ca1800 100644
--- a/go.sum
+++ b/go.sum
@@ -240,12 +240,10 @@ github.com/go-kit/kit v0.8.0/go.mod
h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod
h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod
h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-kit/log v0.1.0/go.mod
h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-kit/log v0.2.0/go.mod
h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod
h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod
h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod
h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod
h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1/go.mod
h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod
h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod
h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -268,6 +266,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible
h1:W1iEw64niKVGogNgBN3ePyL
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod
h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sql-driver/mysql v1.4.0/go.mod
h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod
h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572
h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod
h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod
h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus/v5 v5.0.3/go.mod
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -316,8 +316,8 @@ github.com/golang/protobuf v1.4.3/go.mod
h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod
h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod
h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod
h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3
h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod
h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4
h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod
h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
@@ -544,8 +544,6 @@ github.com/mattn/go-isatty v0.0.16
h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK
github.com/mattn/go-isatty v0.0.16/go.mod
h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod
h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod
h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.4
h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod
h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod
h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod
h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod
h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
@@ -604,7 +602,11 @@ github.com/oliveagle/jsonpath
v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjG
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod
h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
github.com/onsi/ginkgo v1.6.0/go.mod
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo/v2 v2.11.0
h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
+github.com/onsi/ginkgo/v2 v2.11.0/go.mod
h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.4.3/go.mod
h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
+github.com/onsi/gomega v1.27.10/go.mod
h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod
h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer
v0.0.0-20170622124052-a52f23424492/go.mod
h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod
h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -657,16 +659,16 @@ github.com/prometheus/client_golang v1.11.0/go.mod
h1:Z6t4BnS23TR94PD6BsDNk8yVqr
github.com/prometheus/client_golang v1.11.1/go.mod
h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod
h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2/go.mod
h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
-github.com/prometheus/client_golang v1.13.0
h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
-github.com/prometheus/client_golang v1.13.0/go.mod
h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
+github.com/prometheus/client_golang v1.19.1
h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
+github.com/prometheus/client_golang v1.19.1/go.mod
h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod
h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod
h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.3.0
h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
-github.com/prometheus/client_model v0.3.0/go.mod
h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
+github.com/prometheus/client_model v0.5.0
h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
+github.com/prometheus/client_model v0.5.0/go.mod
h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod
h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -677,8 +679,8 @@ github.com/prometheus/common v0.10.0/go.mod
h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8
github.com/prometheus/common v0.15.0/go.mod
h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.26.0/go.mod
h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod
h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.37.0
h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
-github.com/prometheus/common v0.37.0/go.mod
h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
+github.com/prometheus/common v0.48.0
h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
+github.com/prometheus/common v0.48.0/go.mod
h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod
h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod
h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod
h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -688,9 +690,13 @@ github.com/prometheus/procfs v0.1.3/go.mod
h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.2.0/go.mod
h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod
h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod
h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.8.0
h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
-github.com/prometheus/procfs v0.8.0/go.mod
h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/procfs v0.12.0
h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
+github.com/prometheus/procfs v0.12.0/go.mod
h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/prometheus/tsdb v0.7.1/go.mod
h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
+github.com/quic-go/qpack v0.5.1/go.mod
h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
+github.com/quic-go/quic-go v0.52.0
h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
+github.com/quic-go/quic-go v0.52.0/go.mod
h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod
h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rhnvrm/simples3 v0.6.1/go.mod
h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod
h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -753,8 +759,9 @@ github.com/streadway/handy
v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
github.com/stretchr/objx v0.1.0/go.mod
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod
h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod
h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod
h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod
h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod
h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod
h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -764,8 +771,8 @@ github.com/stretchr/testify v1.7.0/go.mod
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod
h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod
h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4
h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/stretchr/testify v1.8.4/go.mod
h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0
h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod
h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0
h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod
h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tebeka/strftime v0.1.3/go.mod
h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
@@ -877,6 +884,8 @@ go.uber.org/atomic v1.10.0/go.mod
h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.11/go.mod
h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod
h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.1.0/go.mod
h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod
h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod
h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
@@ -903,8 +912,8 @@ golang.org/x/crypto
v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
-golang.org/x/crypto v0.21.0/go.mod
h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod
h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -947,6 +956,8 @@ golang.org/x/mod v0.4.0/go.mod
h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod
h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -997,12 +1008,10 @@ golang.org/x/net
v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
-golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1017,7 +1026,6 @@ golang.org/x/oauth2
v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod
h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod
h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod
h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod
h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1030,8 +1038,8 @@ golang.org/x/sync
v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1118,8 +1126,8 @@ golang.org/x/sys
v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
+golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1133,8 +1141,8 @@ golang.org/x/text v0.3.5/go.mod
h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod
h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod
h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1207,6 +1215,8 @@ golang.org/x/tools v0.1.1/go.mod
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod
h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod
h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1351,8 +1361,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod
h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.31.0
h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0
h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod
h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod
h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod
h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/protocol/options.go b/protocol/options.go
index c3f1e58e2..28629f7c0 100644
--- a/protocol/options.go
+++ b/protocol/options.go
@@ -120,13 +120,13 @@ func NewServerOptions(opts ...ServerOption)
*ServerOptions {
}
type ClientOptions struct {
- ProtocolClient *global.ProtocolClientConfig
+ ProtocolClient *global.ClientProtocolConfig
ID string
}
func defaultClientOptions() *ClientOptions {
- return &ClientOptions{ProtocolClient:
global.DefaultProtocolClientConfig()}
+ return &ClientOptions{ProtocolClient:
global.DefaultClientProtocolConfig()}
}
func NewClientOptions(opts ...ClientOption) *ClientOptions {
diff --git a/protocol/triple/client.go b/protocol/triple/client.go
index f52b169db..34022421c 100644
--- a/protocol/triple/client.go
+++ b/protocol/triple/client.go
@@ -35,6 +35,9 @@ import (
"github.com/dustin/go-humanize"
"golang.org/x/net/http2"
+
+ "github.com/quic-go/quic-go"
+ "github.com/quic-go/quic-go/http3"
)
import (
@@ -184,26 +187,48 @@ func newClientManager(url *common.URL) (*clientManager,
error) {
}
}
- cliKeepAliveOpts, keepAliveInterval, keepAliveTimeout,
genKeepAliveOptsErr := genKeepAliveOpts(url)
+ var tripleConf *global.TripleConfig
+
+ tripleConfRaw, ok := url.GetAttribute(constant.TripleConfigKey)
+ if ok {
+ tripleConf = tripleConfRaw.(*global.TripleConfig)
+ }
+
+ // handle keepalive options
+ cliKeepAliveOpts, keepAliveInterval, keepAliveTimeout,
genKeepAliveOptsErr := genKeepAliveOptions(url, tripleConf)
if genKeepAliveOptsErr != nil {
logger.Errorf("genKeepAliveOpts err: %v", genKeepAliveOptsErr)
return nil, genKeepAliveOptsErr
}
-
cliOpts = append(cliOpts, cliKeepAliveOpts...)
+ // handle http transport of triple protocol
var transport http.RoundTripper
- callType := url.GetParam(constant.CallHTTPTypeKey, constant.CallHTTP2)
- switch callType {
+
+ var callProtocol string
+ if tripleConf != nil && tripleConf.Http3 != nil &&
tripleConf.Http3.Enable {
+ callProtocol = constant.CallHTTP3
+ } else {
+ // HTTP default type is HTTP/2.
+ callProtocol = constant.CallHTTP2
+ }
+
+ switch callProtocol {
+ // This case might be for backward compatibility,
+ // it's not useful for the Triple protocol, HTTP/1 lacks trailer
functionality.
+ // Triple protocol only supports HTTP/2 and HTTP/3.
case constant.CallHTTP:
transport = &http.Transport{
TLSClientConfig: cfg,
}
cliOpts = append(cliOpts, tri.WithTriple())
case constant.CallHTTP2:
+ // TODO: Enrich the http2 transport config for triple protocol.
if tlsFlag {
transport = &http2.Transport{
TLSClientConfig: cfg,
+ ReadIdleTimeout: keepAliveInterval,
+ PingTimeout: keepAliveTimeout,
}
} else {
transport = &http2.Transport{
@@ -215,9 +240,27 @@ func newClientManager(url *common.URL) (*clientManager,
error) {
PingTimeout: keepAliveTimeout,
}
}
+ case constant.CallHTTP3:
+ if !tlsFlag {
+ return nil, fmt.Errorf("TRIPLE http3 client must have
TLS config, but TLS config is nil")
+ }
+
+ // TODO: Enrich the http3 transport config for triple protocol.
+ transport = &http3.Transport{
+ TLSClientConfig: cfg,
+ QUICConfig: &quic.Config{
+ // ref:
https://quic-go.net/docs/quic/connection/#keeping-a-connection-alive
+ KeepAlivePeriod: keepAliveInterval,
+ // ref:
https://quic-go.net/docs/quic/connection/#idle-timeout
+ MaxIdleTimeout: keepAliveTimeout,
+ },
+ }
+
+ logger.Infof("Triple http3 client transport init successfully")
default:
- panic(fmt.Sprintf("Unsupported callType: %s", callType))
+ return nil, fmt.Errorf("unsupported http protocol: %s",
callProtocol)
}
+
httpClient := &http.Client{
Transport: transport,
}
@@ -230,6 +273,7 @@ func newClientManager(url *common.URL) (*clientManager,
error) {
} else {
baseTriURL = httpPrefix + baseTriURL
}
+
triClients := make(map[string]*tri.Client)
if len(url.Methods) != 0 {
@@ -268,7 +312,7 @@ func newClientManager(url *common.URL) (*clientManager,
error) {
}, nil
}
-func genKeepAliveOpts(url *common.URL) ([]tri.ClientOption, time.Duration,
time.Duration, error) {
+func genKeepAliveOptions(url *common.URL, tripleConf *global.TripleConfig)
([]tri.ClientOption, time.Duration, time.Duration, error) {
var cliKeepAliveOpts []tri.ClientOption
// set max send and recv msg size
@@ -289,26 +333,22 @@ func genKeepAliveOpts(url *common.URL)
([]tri.ClientOption, time.Duration, time.
keepAliveInterval := url.GetParamDuration(constant.KeepAliveInterval,
constant.DefaultKeepAliveInterval)
keepAliveTimeout := url.GetParamDuration(constant.KeepAliveTimeout,
constant.DefaultKeepAliveTimeout)
- tripleConfRaw, ok := url.GetAttribute(constant.TripleConfigKey)
- if ok {
- var parseErr error
- tripleConf := tripleConfRaw.(*global.TripleConfig)
+ if tripleConf == nil {
+ return cliKeepAliveOpts, keepAliveInterval, keepAliveTimeout,
nil
+ }
- if tripleConf == nil {
- return cliKeepAliveOpts, keepAliveInterval,
keepAliveTimeout, nil
- }
+ var parseErr error
- if tripleConf.KeepAliveInterval != "" {
- keepAliveInterval, parseErr =
time.ParseDuration(tripleConf.KeepAliveInterval)
- if parseErr != nil {
- return nil, 0, 0, parseErr
- }
+ if tripleConf.KeepAliveInterval != "" {
+ keepAliveInterval, parseErr =
time.ParseDuration(tripleConf.KeepAliveInterval)
+ if parseErr != nil {
+ return nil, 0, 0, parseErr
}
- if tripleConf.KeepAliveTimeout != "" {
- keepAliveTimeout, parseErr =
time.ParseDuration(tripleConf.KeepAliveTimeout)
- if parseErr != nil {
- return nil, 0, 0, parseErr
- }
+ }
+ if tripleConf.KeepAliveTimeout != "" {
+ keepAliveTimeout, parseErr =
time.ParseDuration(tripleConf.KeepAliveTimeout)
+ if parseErr != nil {
+ return nil, 0, 0, parseErr
}
}
diff --git a/protocol/triple/options.go b/protocol/triple/options.go
index b1b634a52..a83164dce 100644
--- a/protocol/triple/options.go
+++ b/protocol/triple/options.go
@@ -92,3 +92,16 @@ func WithMaxServerRecvMsgSize(size string) Option {
opts.Triple.MaxServerRecvMsgSize = size
}
}
+
+// Http3Enable enables HTTP/3 support for the Triple protocol.
+// It sets the corresponding configuration to enable HTTP/3.
+//
+// # Experimental
+//
+// NOTICE: This API is EXPERIMENTAL and may be changed or removed in
+// a later release.
+func Http3Enable() Option {
+ return func(opts *Options) {
+ opts.Triple.Http3.Enable = true
+ }
+}
diff --git a/protocol/triple/server.go b/protocol/triple/server.go
index 50be3ab93..076b15210 100644
--- a/protocol/triple/server.go
+++ b/protocol/triple/server.go
@@ -19,6 +19,7 @@ package triple
import (
"context"
+ "crypto/tls"
"fmt"
"net/http"
"reflect"
@@ -71,12 +72,28 @@ func NewServer(cfg *global.TripleConfig) *Server {
// Start TRIPLE server
func (s *Server) Start(invoker base.Invoker, info *common.ServiceInfo) {
- URL := invoker.GetURL()
- addr := URL.Location
+ url := invoker.GetURL()
+ addr := url.Location
+
+ var tripleConf *global.TripleConfig
+
+ tripleConfRaw, ok := url.GetAttribute(constant.TripleConfigKey)
+ if ok {
+ tripleConf = tripleConfRaw.(*global.TripleConfig)
+ }
+
+ var callProtocol string
+ if tripleConf != nil && tripleConf.Http3 != nil &&
tripleConf.Http3.Enable {
+ callProtocol = constant.CallHTTP3
+ } else {
+ // HTTP default type is HTTP/2.
+ callProtocol = constant.CallHTTP2
+ }
+
// initialize tri.Server
s.triServer = tri.NewServer(addr)
- serialization := URL.GetParam(constant.SerializationKey,
constant.ProtobufSerialization)
+ serialization := url.GetParam(constant.SerializationKey,
constant.ProtobufSerialization)
switch serialization {
case constant.ProtobufSerialization:
case constant.JSONSerialization:
@@ -89,41 +106,44 @@ func (s *Server) Start(invoker base.Invoker, info
*common.ServiceInfo) {
// TODO: move tls config to handleService
- var tlsConf *global.TLSConfig
+ var globalTlsConf *global.TLSConfig
+ var tlsConf *tls.Config
+ var err error
// handle tls
- tlsConfRaw, ok := URL.GetAttribute(constant.TLSConfigKey)
+ tlsConfRaw, ok := url.GetAttribute(constant.TLSConfigKey)
if ok {
- tlsConf, ok = tlsConfRaw.(*global.TLSConfig)
+ globalTlsConf, ok = tlsConfRaw.(*global.TLSConfig)
if !ok {
logger.Errorf("TRIPLE Server initialized the TLSConfig
configuration failed")
return
}
}
- if dubbotls.IsServerTLSValid(tlsConf) {
- cfg, err := dubbotls.GetServerTlSConfig(tlsConf)
+ if dubbotls.IsServerTLSValid(globalTlsConf) {
+ tlsConf, err = dubbotls.GetServerTlSConfig(globalTlsConf)
if err != nil {
logger.Errorf("TRIPLE Server initialized the TLSConfig
configuration failed. err: %v", err)
return
}
- s.triServer.SetTLSConfig(cfg)
logger.Infof("TRIPLE Server initialized the TLSConfig
configuration")
}
// IDLMode means that this will only be set when
// the new triple is started in non-IDL mode.
// TODO: remove IDLMode when config package is removed
- IDLMode := URL.GetParam(constant.IDLMode, "")
+ IDLMode := url.GetParam(constant.IDLMode, "")
var service common.RPCService
if IDLMode == constant.NONIDL {
- service, _ = URL.GetAttribute(constant.RpcServiceKey)
+ service, _ = url.GetAttribute(constant.RpcServiceKey)
}
- hanOpts := getHanOpts(URL)
+ hanOpts := getHanOpts(url, tripleConf)
+
//Set expected codec name from serviceinfo
hanOpts = append(hanOpts, tri.WithExpectedCodecName(serialization))
- intfName := URL.Interface()
+
+ intfName := url.Interface()
if info != nil {
// new triple idl mode
s.handleServiceWithInfo(intfName, invoker, info, hanOpts...)
@@ -135,12 +155,12 @@ func (s *Server) Start(invoker base.Invoker, info
*common.ServiceInfo) {
s.saveServiceInfo(intfName, reflectInfo)
} else {
// old triple idl mode and old triple non-idl mode
- s.compatHandleService(intfName, URL.Group(), URL.Version(),
hanOpts...)
+ s.compatHandleService(intfName, url.Group(), url.Version(),
hanOpts...)
}
internal.ReflectionRegister(s)
go func() {
- if runErr := s.triServer.Run(); runErr != nil {
+ if runErr := s.triServer.Run(callProtocol, tlsConf); runErr !=
nil {
logger.Errorf("server serve failed with err: %v",
runErr)
}
}()
@@ -159,7 +179,7 @@ func (s *Server) RefreshService(invoker base.Invoker, info
*common.ServiceInfo)
default:
panic(fmt.Sprintf("Unsupported serialization: %s",
serialization))
}
- hanOpts := getHanOpts(URL)
+ hanOpts := getHanOpts(URL, s.cfg)
//Set expected codec name from serviceinfo
hanOpts = append(hanOpts, tri.WithExpectedCodecName(serialization))
intfName := URL.Interface()
@@ -171,14 +191,13 @@ func (s *Server) RefreshService(invoker base.Invoker,
info *common.ServiceInfo)
}
}
-func getHanOpts(url *common.URL) (hanOpts []tri.HandlerOption) {
+func getHanOpts(url *common.URL, tripleConf *global.TripleConfig) (hanOpts
[]tri.HandlerOption) {
group := url.GetParam(constant.GroupKey, "")
version := url.GetParam(constant.VersionKey, "")
hanOpts = append(hanOpts, tri.WithGroup(group),
tri.WithVersion(version))
// Deprecated:use TripleConfig
// TODO: remove MaxServerSendMsgSize and MaxServerRecvMsgSize when
version 4.0.0
- var err error
maxServerRecvMsgSize := constant.DefaultMaxServerRecvMsgSize
if recvMsgSize, convertErr :=
humanize.ParseBytes(url.GetParam(constant.MaxServerRecvMsgSize, ""));
convertErr == nil && recvMsgSize != 0 {
maxServerRecvMsgSize = int(recvMsgSize)
@@ -188,24 +207,17 @@ func getHanOpts(url *common.URL) (hanOpts
[]tri.HandlerOption) {
// Deprecated:use TripleConfig
// TODO: remove MaxServerSendMsgSize and MaxServerRecvMsgSize when
version 4.0.0
maxServerSendMsgSize := constant.DefaultMaxServerSendMsgSize
- if sendMsgSize, convertErr :=
humanize.ParseBytes(url.GetParam(constant.MaxServerSendMsgSize, "")); err ==
convertErr && sendMsgSize != 0 {
+ if sendMsgSize, convertErr :=
humanize.ParseBytes(url.GetParam(constant.MaxServerSendMsgSize, ""));
convertErr == nil && sendMsgSize != 0 {
maxServerSendMsgSize = int(sendMsgSize)
}
hanOpts = append(hanOpts, tri.WithSendMaxBytes(maxServerSendMsgSize))
- var tripleConf *global.TripleConfig
-
- tripleConfRaw, ok := url.GetAttribute(constant.TripleConfigKey)
- if ok {
- tripleConf = tripleConfRaw.(*global.TripleConfig)
- }
-
if tripleConf == nil {
return hanOpts
}
if tripleConf.MaxServerRecvMsgSize != "" {
- logger.Warnf("MaxServerRecvMsgSize: %v",
tripleConf.MaxServerRecvMsgSize)
+ logger.Debugf("MaxServerRecvMsgSize: %v",
tripleConf.MaxServerRecvMsgSize)
if recvMsgSize, convertErr :=
humanize.ParseBytes(tripleConf.MaxServerRecvMsgSize); convertErr == nil &&
recvMsgSize != 0 {
maxServerRecvMsgSize = int(recvMsgSize)
}
@@ -213,8 +225,8 @@ func getHanOpts(url *common.URL) (hanOpts
[]tri.HandlerOption) {
}
if tripleConf.MaxServerSendMsgSize != "" {
- logger.Warnf("MaxServerSendMsgSize: %v",
tripleConf.MaxServerSendMsgSize)
- if sendMsgSize, convertErr :=
humanize.ParseBytes(tripleConf.MaxServerSendMsgSize); err == convertErr &&
sendMsgSize != 0 {
+ logger.Debugf("MaxServerSendMsgSize: %v",
tripleConf.MaxServerSendMsgSize)
+ if sendMsgSize, convertErr :=
humanize.ParseBytes(tripleConf.MaxServerSendMsgSize); convertErr == nil &&
sendMsgSize != 0 {
maxServerSendMsgSize = int(sendMsgSize)
}
hanOpts = append(hanOpts,
tri.WithSendMaxBytes(maxServerSendMsgSize))
diff --git a/protocol/triple/triple_protocol/server.go
b/protocol/triple/triple_protocol/server.go
index 3efbe73ce..a7089220f 100644
--- a/protocol/triple/triple_protocol/server.go
+++ b/protocol/triple/triple_protocol/server.go
@@ -20,7 +20,10 @@ package triple_protocol
import (
"context"
"crypto/tls"
+ "errors"
+ "fmt"
"net/http"
+ "strings"
"sync"
)
@@ -31,13 +34,22 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
+
+ "github.com/quic-go/quic-go"
+ "github.com/quic-go/quic-go/http3"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
)
type Server struct {
mu sync.Mutex
+ addr string
mux *http.ServeMux
handlers map[string]*Handler
httpSrv *http.Server
+ http3Srv *http3.Server
}
func (s *Server) RegisterUnaryHandler(
@@ -160,44 +172,158 @@ func (s *Server) RegisterCompatStreamHandler(
return nil
}
-func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- handler, pattern := s.mux.Handler(r)
- if pattern == "" {
- logger.Warnf("404: didn't register this method - %s\n",
r.URL.Path)
+func (s *Server) Run(callProtocol string, tlsConf *tls.Config) error {
+ // TODO: Refactor to support starting HTTP/2 and HTTP/3 servers
simultaneously.
+ // The current switch logic is mutually exclusive. Future work should
allow enabling
+ // both protocols, likely based on configuration, and run them
concurrently.
+ switch callProtocol {
+ case constant.CallHTTP2:
+ return s.startHttp2(tlsConf)
+ case constant.CallHTTP3:
+ return s.startHttp3(tlsConf)
+ default:
+ return fmt.Errorf("unsupported protocol: %s, only http2 or
http3 are supported", callProtocol)
}
-
- handler.ServeHTTP(w, r)
}
-func (s *Server) Run() error {
- s.httpSrv.Handler = h2c.NewHandler(s, &http2.Server{})
+func (s *Server) startHttp2(tlsConf *tls.Config) error {
+ s.httpSrv = &http.Server{
+ Addr: s.addr,
+ Handler: h2c.NewHandler(s.mux, &http2.Server{}),
+ TLSConfig: tlsConf,
+ }
+
+ logger.Debugf("TRIPLE HTTP/2 Server starting on %v", s.addr)
var err error
- if s.httpSrv.TLSConfig != nil {
- // TODO: Maybe we should be able to find a better way to start
TLS.
+
+ if tlsConf != nil {
err = s.httpSrv.ListenAndServeTLS("", "")
} else {
err = s.httpSrv.ListenAndServe()
}
+
return err
}
-func (s *Server) SetTLSConfig(c *tls.Config) {
- s.httpSrv.TLSConfig = c
+func (s *Server) startHttp3(tlsConf *tls.Config) error {
+ if tlsConf == nil {
+ return fmt.Errorf("TRIPLE HTTP/3 Server must have TLS config,
but TLS config is nil")
+ }
+
+ s.http3Srv = &http3.Server{
+ Addr: s.addr,
+ Handler: s.mux,
+ // Adapt and enhance a generic tls.Config object into a
configuration
+ // specifically for HTTP/3 services.
+ // ref:
https://quic-go.net/docs/http3/server/#setting-up-a-http3server
+ TLSConfig: http3.ConfigureTLSConfig(tlsConf),
+ // TODO: Detailed QUIC configuration.
+ QUICConfig: &quic.Config{},
+ }
+
+ logger.Debugf("TRIPLE HTTP/3 Server starting on %v", s.addr)
+
+ return s.http3Srv.ListenAndServe()
}
+// Stop the Triple server for both HTTP/2 and HTTP/3.
+// Because stop is very fast, there is no need to parallelize stop.
func (s *Server) Stop() error {
- return s.httpSrv.Close()
+ var errs []error
+
+ // stop HTTP server
+ if s.httpSrv != nil {
+ if err := s.httpSrv.Close(); err != nil {
+ errs = append(errs, fmt.Errorf("http server close
failed: %w", err))
+ }
+ }
+
+ // stop HTTP/3 server
+ if s.http3Srv != nil {
+ if err := s.http3Srv.Close(); err != nil {
+ errs = append(errs, fmt.Errorf("http3 server close
failed: %w", err))
+ }
+ }
+
+ switch len(errs) {
+ case 0:
+ return nil
+ case 1:
+ return errs[0]
+ default:
+ var sb strings.Builder
+ sb.WriteString("multiple errors occurred during stop:")
+ for _, err := range errs {
+ // Newline and indent for easier reading
+ sb.WriteString("\n\t- ")
+ sb.WriteString(err.Error())
+ }
+ return errors.New(sb.String())
+ }
}
+// Gracefulstop shutdown the Triple server for both HTTP/2 and HTTP/3
gracefully.
+// Because graceful shutdown is slow, I adopted concurrent processing.
func (s *Server) GracefulStop(ctx context.Context) error {
- return s.httpSrv.Shutdown(ctx)
+ var (
+ wg sync.WaitGroup
+ errChan = make(chan error, 2)
+ )
+
+ // shutdown HTTP server
+ if s.httpSrv != nil {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err := s.httpSrv.Shutdown(ctx); err != nil {
+ errChan <- fmt.Errorf("http server shutdown
failed: %w", err)
+ }
+ }()
+ }
+
+ // shutdown HTTP/3 server
+ if s.http3Srv != nil {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err := s.http3Srv.Shutdown(ctx); err != nil {
+ errChan <- fmt.Errorf("http3 server shutdown
failed: %w", err)
+ }
+ }()
+ }
+
+ wg.Wait()
+ close(errChan)
+
+ // Error Collection and Handling.
+ // Collect all errors into a slice.
+ var errs []error
+ for err := range errChan {
+ errs = append(errs, err)
+ }
+
+ switch len(errs) {
+ case 0:
+ return nil
+ case 1:
+ return errs[0]
+ default:
+ var sb strings.Builder
+ sb.WriteString("multiple errors occurred during graceful stop:")
+ for _, err := range errs {
+ // Newline and indent for easier reading
+ sb.WriteString("\n\t- ")
+ sb.WriteString(err.Error())
+ }
+ return errors.New(sb.String())
+ }
}
func NewServer(addr string) *Server {
return &Server{
mux: http.NewServeMux(),
+ addr: addr,
handlers: make(map[string]*Handler),
- httpSrv: &http.Server{Addr: addr},
}
}