refactor: sync sparse tlprofile runtime
This commit is contained in:
parent
5ecf4e912d
commit
25ab04a254
93 changed files with 2983 additions and 1615 deletions
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/iamxvbaba/td/proto"
|
||||
"github.com/iamxvbaba/td/tg"
|
||||
|
||||
"github.com/iamxvbaba/td/tlprofile"
|
||||
compatandroid "telesrv/internal/compat/android"
|
||||
"telesrv/internal/domain"
|
||||
"telesrv/internal/observability/dbtrace"
|
||||
|
|
@ -90,7 +91,7 @@ type Config struct {
|
|||
TempKeyResolveCacheMaxEntries int
|
||||
}
|
||||
|
||||
// Router 把解密后的 RPC 请求按 TypeID 路由到 typed handler(tg.ServerDispatcher)。
|
||||
// Router 把解密后的 RPC 请求按 semantic method 路由到 typed handler(tlprofile.Dispatcher)。
|
||||
//
|
||||
// handler 输入输出均为 iamxvbaba/td/tg 类型,各业务域的 handler
|
||||
// 与注册见 help.go / auth.go / users.go / updates.go。Router 本身只负责协议外壳:
|
||||
|
|
@ -100,7 +101,7 @@ type Router struct {
|
|||
log *zap.Logger
|
||||
clock clock.Clock
|
||||
deps Deps
|
||||
dispatcher *tg.ServerDispatcher
|
||||
dispatcher *tlprofile.Dispatcher
|
||||
clientInfoMu sync.RWMutex
|
||||
clientInfo map[clientInfoSessionKey]clientSessionInfo
|
||||
authInfo map[[8]byte]clientSessionInfo
|
||||
|
|
@ -244,12 +245,12 @@ func New(cfg Config, deps Deps, log *zap.Logger, clk clock.Clock) *Router {
|
|||
if cfg.DC > 0 {
|
||||
groupCallStreamDCID = cfg.DC
|
||||
}
|
||||
d := tg.NewServerDispatcher(r.fallback)
|
||||
d := tlprofile.NewDispatcher()
|
||||
if err := registerLayerRPCAdmissionFieldPreflights(d); err != nil {
|
||||
panic(fmt.Sprintf("register exact layer RPC admission policy: %v", err))
|
||||
}
|
||||
r.registerAndroidLayerRPCAdapter(d)
|
||||
d.OnLayerRPCWrappers(r.consumeLayerRPCWrappers)
|
||||
d.OnWrappers(r.consumeLayerRPCWrappers)
|
||||
|
||||
r.registerHelp(d)
|
||||
r.registerAuth(d)
|
||||
|
|
@ -278,6 +279,22 @@ func New(cfg Config, deps Deps, log *zap.Logger, clk clock.Clock) *Router {
|
|||
return r
|
||||
}
|
||||
|
||||
func registerRPC[T bin.Object](d *tlprofile.Dispatcher, method tlprofile.SemanticID, handler func(context.Context, T) (any, error)) {
|
||||
if d == nil || handler == nil {
|
||||
panic("rpc: register nil canonical RPC handler or dispatcher")
|
||||
}
|
||||
err := d.Register(method, func(ctx context.Context, object bin.Object) (any, error) {
|
||||
request, ok := object.(T)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("rpc: semantic %#016x decoded unexpected canonical request %T", uint64(method), object)
|
||||
}
|
||||
return handler(ctx, request)
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("rpc: register canonical RPC %#016x: %v", uint64(method), err))
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch routes one RPC and preserves the historical two-value API used by
|
||||
// domain/RPC tests. The MTProto edge uses DispatchWithMethod so outbound
|
||||
// scheduling sees the exact innermost method rather than an invoke wrapper.
|
||||
|
|
@ -622,14 +639,14 @@ func (r *Router) dispatch(ctx context.Context, b *bin.Buffer, depth int, meta *r
|
|||
// Router.Dispatch is a legacy test seam. Production uses generated exact
|
||||
// Layer admission, whose unknown-method view invokes the same static DrKLO
|
||||
// overlay while sharing the outer request budget.
|
||||
profile := tlprofile.ProfileCanonical
|
||||
if selected, ok := tlprofile.ResolveProfile(LayerFrom(ctx)); ok {
|
||||
profile = selected
|
||||
}
|
||||
if id != 0 {
|
||||
profile := tg.LayerProfileCanonical
|
||||
if selected, ok := tg.ResolveLayerProfile(LayerFrom(ctx)); ok {
|
||||
profile = selected
|
||||
}
|
||||
_, official := tg.LayerSemanticForWireID(profile, id)
|
||||
_, official := tlprofile.SemanticForWireID(profile, id)
|
||||
if !official {
|
||||
if up, ok, err := compatandroid.UpgradePrivateLayerRPC(profile, b, tg.LayerDecodeLimits{}); ok {
|
||||
if up, ok, err := compatandroid.UpgradePrivateLayerRPC(profile, b, tlprofile.Limits{}); ok {
|
||||
if err != nil {
|
||||
return nil, inputRequestInvalidErr()
|
||||
}
|
||||
|
|
@ -648,15 +665,18 @@ func (r *Router) dispatch(ctx context.Context, b *bin.Buffer, depth int, meta *r
|
|||
if meta != nil {
|
||||
meta.method = tlTypeName(id)
|
||||
}
|
||||
semantic, knownRequest := tg.LayerSemanticForWireID(tg.LayerProfileCanonical, id)
|
||||
semantic, knownRequest := tlprofile.SemanticForWireID(tlprofile.ProfileCanonical, id)
|
||||
if knownRequest {
|
||||
category, _, named := tg.LayerSemanticName(semantic)
|
||||
category, _, named := tlprofile.SemanticName(semantic)
|
||||
knownRequest = named && category == "function"
|
||||
}
|
||||
if !knownRequest {
|
||||
// Unknown methods remain opaque and go to the compatibility trace.
|
||||
return r.fallback(ctx, b)
|
||||
}
|
||||
if !r.dispatcher.Has(semantic) {
|
||||
return r.fallback(ctx, b)
|
||||
}
|
||||
if r.deps.Auth != nil {
|
||||
if _, ok := UserIDFrom(ctx); !ok && !rpcAllowedWithoutAuthorization(id) {
|
||||
fields := append([]zap.Field{
|
||||
|
|
@ -680,7 +700,17 @@ func (r *Router) dispatch(ctx context.Context, b *bin.Buffer, depth int, meta *r
|
|||
r.maybeMarkSessionReceivesUpdates(ctx)
|
||||
dbBefore := dbtrace.SnapshotFromContext(ctx)
|
||||
start := time.Now()
|
||||
enc, err := r.dispatcher.Handle(ctx, b)
|
||||
admission, err := r.dispatcher.Admit(profile, b, tlprofile.Limits{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
exact, err := r.dispatcher.Dispatch(ctx, admission)
|
||||
var enc bin.Encoder = exact
|
||||
if err == nil && exact != nil {
|
||||
if canonical, ok := exact.CanonicalValue().(bin.Encoder); ok {
|
||||
enc = canonical
|
||||
}
|
||||
}
|
||||
dur := time.Since(start)
|
||||
dbDelta := dbtrace.SnapshotFromContext(ctx).Sub(dbBefore)
|
||||
fields := append([]zap.Field{
|
||||
|
|
@ -1026,7 +1056,7 @@ func (r *Router) FreezeNegotiatedSessionLayerAt(authKeyID [8]byte, sessionID int
|
|||
if r == nil || authKeyID == ([8]byte{}) || sessionID == 0 {
|
||||
return false, errors.New("invalid exact session profile identity")
|
||||
}
|
||||
profile, ok := tg.ResolveLayerProfile(layer)
|
||||
profile, ok := tlprofile.ResolveProfile(layer)
|
||||
if !ok || int(profile) != layer {
|
||||
return false, fmt.Errorf("unsupported exact session profile %d", layer)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue