Files
x/ctx/value.go
T
ginuerzh 419f4c4c73 docs(ctx): add doc comments, remove dead WithContext interface, simplify HashFromContext
Remove unused WithContext interface (zero references in codebase), add
doc comments for all 14 exported symbols, and simplify HashFromContext
to match the one-liner pattern used by the other four getters.
Add 22 unit tests covering round-trip, empty context, wrong type, nil
values, multiple values, independent keys, and the Context interface.
2026-05-24 14:26:45 +08:00

103 lines
2.9 KiB
Go

// Package ctx provides typed context keys and helpers for passing per-request
// data (session ID, addresses, client ID, hash source) through the handler chain.
package ctx
import (
"context"
"net"
)
// Context is implemented by connections that carry a [context.Context].
type Context interface {
Context() context.Context
}
type srcAddrKey struct{}
// ContextWithSrcAddr returns a copy of ctx that carries the source address addr.
func ContextWithSrcAddr(ctx context.Context, addr net.Addr) context.Context {
return context.WithValue(ctx, srcAddrKey{}, addr)
}
// SrcAddrFromContext returns the source address stored in ctx, or nil if none is set.
func SrcAddrFromContext(ctx context.Context) net.Addr {
v, _ := ctx.Value(srcAddrKey{}).(net.Addr)
return v
}
type dstAddrKey struct{}
// ContextWithDstAddr returns a copy of ctx that carries the destination address addr.
func ContextWithDstAddr(ctx context.Context, addr net.Addr) context.Context {
return context.WithValue(ctx, dstAddrKey{}, addr)
}
// DstAddrFromContext returns the destination address stored in ctx, or nil if none is set.
func DstAddrFromContext(ctx context.Context) net.Addr {
v, _ := ctx.Value(dstAddrKey{}).(net.Addr)
return v
}
type (
// Sid is a session identifier carried in the context.
Sid string
sidKey struct{}
)
// String implements fmt.Stringer.
func (s Sid) String() string {
return string(s)
}
// ContextWithSid returns a copy of ctx that carries the session ID sid.
func ContextWithSid(ctx context.Context, sid Sid) context.Context {
return context.WithValue(ctx, sidKey{}, sid)
}
// SidFromContext returns the session ID stored in ctx, or the zero value if none is set.
func SidFromContext(ctx context.Context) Sid {
v, _ := ctx.Value(sidKey{}).(Sid)
return v
}
type (
hashKey struct{}
// Hash carries the hash source used by selectors for sticky load balancing.
Hash struct {
Source string
}
)
// ContextWithHash returns a copy of ctx that carries the hash source h.
func ContextWithHash(ctx context.Context, h *Hash) context.Context {
return context.WithValue(ctx, hashKey{}, h)
}
// HashFromContext returns the hash source stored in ctx, or nil if none is set.
func HashFromContext(ctx context.Context) *Hash {
v, _ := ctx.Value(hashKey{}).(*Hash)
return v
}
type (
// ClientID is a client identifier used for hash-based load balancing.
ClientID string
clientIDKey struct{}
)
// String implements fmt.Stringer.
func (c ClientID) String() string {
return string(c)
}
// ContextWithClientID returns a copy of ctx that carries the client ID clientID.
func ContextWithClientID(ctx context.Context, clientID ClientID) context.Context {
return context.WithValue(ctx, clientIDKey{}, clientID)
}
// ClientIDFromContext returns the client ID stored in ctx, or the zero value if none is set.
func ClientIDFromContext(ctx context.Context) ClientID {
v, _ := ctx.Value(clientIDKey{}).(ClientID)
return v
}