[management] batch disconnect and lock free reconnect (#8373)

This commit is contained in:
Pascal Fischer
2026-10-27 16:24:46 +01:00
committed by GitHub
parent 36339993bc
commit 09f1de12e8
18 changed files with 1094 additions and 144 deletions
+33 -4
View File
@@ -1,6 +1,9 @@
package server
import "fmt"
import (
"fmt"
"reflect"
)
// Create a dependency and add it to the BaseServer's container. A string key identifier will be based on its type definition.
func Create[T any](s Server, createFunc func() T) T {
@@ -33,15 +36,41 @@ func InjectNamed[T any](c Server, name string, thing T) {
}
func maybeCreate[T any](s Server, createFunc func() T) (result T, isNew bool) {
key := fmt.Sprintf("%T", (*T)(nil))[1:]
return maybeCreateKeyed(s, key, createFunc)
return maybeCreateKeyed(s, typeKey(reflect.TypeFor[T]()), createFunc)
}
func maybeCreateNamed[T any](s Server, name string, createFunc func() T) (result T, isNew bool) {
key := fmt.Sprintf("%T:%s", (*T)(nil), name)[1:]
key := fmt.Sprintf("%s:%s", typeKey(reflect.TypeFor[T]()), name)
return maybeCreateKeyed(s, key, createFunc)
}
// typeKey names t by the full package path of every named type it is built from, so
// same-named types of different packages, such as google.golang.org/grpc.Server and a
// local grpc.Server, never share a container key.
func typeKey(t reflect.Type) string {
if t.Name() != "" {
if t.PkgPath() == "" {
return t.Name()
}
return t.PkgPath() + "." + t.Name()
}
switch t.Kind() {
case reflect.Pointer:
return "*" + typeKey(t.Elem())
case reflect.Slice:
return "[]" + typeKey(t.Elem())
case reflect.Array:
return fmt.Sprintf("[%d]%s", t.Len(), typeKey(t.Elem()))
case reflect.Map:
return "map[" + typeKey(t.Key()) + "]" + typeKey(t.Elem())
case reflect.Chan:
return t.ChanDir().String() + " " + typeKey(t.Elem())
default:
return t.String()
}
}
func maybeCreateKeyed[T any](s Server, key string, createFunc func() T) (result T, isNew bool) {
if t, ok := s.GetContainer(key); ok {
if t == nil {