contextx

package
v0.19.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 09:55:06 * @FilePath: \go-toolbox\pkg\contextx\core.go * @Description: Context 核心定义和构造函数 * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 11:19:53 * @FilePath: \go-toolbox\pkg\contextx\getters.go * @Description: Context 类型安全的 Getter 方法 * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-02-12 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-02-12 00:00:00 * @FilePath: \go-toolbox\pkg\contextx\grpc.go * @Description: Context metadata 泛型操作接口(轻量级,无外部依赖) * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 10:15:15 * @FilePath: \go-toolbox\pkg\contextx\helpers.go * @Description: Context 全局辅助函数 * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 10:00:00 * @FilePath: \go-toolbox\pkg\contextx\metadata.go * @Description: Context 元数据操作方法 * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 10:00:00 * @FilePath: \go-toolbox\pkg\contextx\utils.go * @Description: Context 工具方法(Clone, Merge, 生命周期等) * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2023-07-28 00:50:58 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-05 10:00:00 * @FilePath: \go-toolbox\pkg\contextx\values.go * @Description: Context 值操作相关方法 * * Copyright (c) 2024 by kamalyes, All Rights Reserved.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrKeyNotFound 键不存在错误
	ErrKeyNotFound = errors.New("key not found in context")
	// ErrMarshalFailed 序列化失败错误
	ErrMarshalFailed = errors.New("failed to marshal value")
	// ErrUnmarshalFailed 反序列化失败错误
	ErrUnmarshalFailed = errors.New("failed to unmarshal value")
)

Functions

func Get

func Get[T any](c *Context, key interface{}) T

Get 泛型获取方法,支持类型推断和转换 使用示例:

str := ctx.Get[string]("key")
num := ctx.Get[int]("count")
flag := ctx.Get[bool]("enabled")

func GetOrDefault

func GetOrDefault[T any](ctx context.Context, key any, defaultValue T) T

GetOrDefault 从上下文中获取值,如果不存在则返回默认值

使用示例:

timeout := contextx.GetOrDefault(ctx, "timeout", 30*time.Second)
userID := contextx.GetOrDefault(ctx, "user_id", "anonymous")

func GetValue

func GetValue[T any](ctx context.Context, key any) T

GetValue 从标准 context.Context 获取指定类型的值(泛型版本,仅支持类型断言)

与 Get 函数的区别:

  • GetValue: 适用于标准 context.Context,key 必须是 string,仅支持类型断言
  • Get: 适用于自定义 *Context,key 可以是任意类型,支持智能类型转换

使用示例:

ctx := context.WithValue(context.Background(), "key", "value")
str := GetValue[string](ctx, "key")  // "value"
num := GetValue[int](ctx, "count")   // 0 (类型不匹配返回零值)

func IsContext

func IsContext(ctx context.Context) bool

IsContext 检查上下文是否是 Context

func MustGet

func MustGet[T any](ctx context.Context, key any) T

MustGet 从上下文中获取值,如果不存在则 panic 这是一个通用的 Must 模式实现

使用示例:

config := contextx.MustGet[*Config](ctx, "config")
userID := contextx.MustGet[string](ctx, "user_id")

func MustGetWithMessage

func MustGetWithMessage[T any](ctx context.Context, key any, message string) T

MustGetWithMessage 从上下文中获取值,如果不存在则 panic 并显示自定义消息

使用示例:

config := contextx.MustGetWithMessage[*Config](ctx, "config", "配置信息不存在于上下文中")

func NewDetachedTimeout

func NewDetachedTimeout(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc)

NewDetachedTimeout 在忽略父 context 取消信号的基础上创建带超时的 context 会保留父 context 的 Value,但不会继承父 context 的 Done 和 Deadline

使用示例:

ctx, cancel := contextx.NewDetachedTimeout(parentCtx, 5*time.Second)
defer cancel()

func OrBackground

func OrBackground(ctx context.Context) context.Context

OrBackground 如果ctx已取消则返回context.Background(),否则返回ctx本身 用于在关闭流程中确保异步任务仍能完成

func OrWithoutCancel

func OrWithoutCancel(ctx context.Context) context.Context

OrWithoutCancel 返回一个忽略父 context 取消信号的新 context 会保留父 context 的 Value,但不会继承父 context 的 Done 和 Deadline 调用方不应传入 nil;如果传入 nil,会回退到 context.Background() 作为防御性兜底

func WithDeadlineDecorators

func WithDeadlineDecorators(deadline time.Time, decorators ...func(context.Context) context.Context) (context.Context, context.CancelFunc)

WithDeadlineDecorators 创建带截止时间的 context 并应用装饰器 支持可选的装饰器函数来增强 context

使用示例:

deadline := time.Now().Add(10 * time.Second)
ctx, cancel := contextx.WithDeadlineDecorators(deadline)
defer cancel()

或者带装饰器
ctx, cancel := contextx.WithDeadlineDecorators(deadline, WithUser(user))
defer cancel()

func WithDetachedTimeout

func WithDetachedTimeout(parent context.Context, timeout time.Duration, fn func(context.Context) error) error

WithDetachedTimeout 在忽略父 context 取消信号的基础上创建带超时的 context 并执行函数 会保留父 context 的 Value,但不会继承父 context 的 Done 和 Deadline

使用示例:

err := contextx.WithDetachedTimeout(h.ctx, 2*time.Second, func(ctx context.Context) error {
    return repo.SaveData(ctx, data)
})

func WithTimeout

func WithTimeout(timeout time.Duration, fn func(context.Context) error) error

WithTimeout 创建带超时的 context 并执行函数 自动处理 cancel 调用,并监听 context 超时

使用示例:

err := contextx.WithTimeout(2*time.Second, func(ctx context.Context) error {
    return repo.SaveData(ctx, data)
})

func WithTimeoutDecorators

func WithTimeoutDecorators(timeout time.Duration, decorators ...func(context.Context) context.Context) (context.Context, context.CancelFunc)

WithTimeoutDecorators 创建带超时的标准 context 并应用装饰器 支持可选的装饰器函数来增强 context

使用示例:

ctx, cancel := contextx.WithTimeoutDecorators(5*time.Second)
defer cancel()

或者带装饰器
ctx, cancel := contextx.WithTimeoutDecorators(5*time.Second, WithUser(user), WithTraceID(id))
defer cancel()

func WithTimeoutFrom

func WithTimeoutFrom(parent context.Context, timeout time.Duration, fn func(context.Context) error) error

WithTimeoutFrom 在指定的父context基础上创建带超时的context并执行函数 自动处理 cancel 调用,并监听 context 超时

使用示例:

err := contextx.WithTimeoutFrom(parentCtx, 2*time.Second, func(ctx context.Context) error {
    return repo.SaveData(ctx, data)
})

func WithTimeoutOrBackground

func WithTimeoutOrBackground(parent context.Context, timeout time.Duration, fn func(context.Context) error) error

WithTimeoutOrBackground 在父context基础上创建带超时的context并执行函数 如果父context已取消,则使用Background作为父context,确保异步任务仍能完成

使用示例:

err := contextx.WithTimeoutOrBackground(h.ctx, 2*time.Second, func(ctx context.Context) error {
    return repo.SaveData(ctx, data)
})

func WithTimeoutValue

func WithTimeoutValue[T any](timeout time.Duration, fn func(context.Context) (T, error)) (T, error)

WithTimeoutValue 创建带超时的 context 并执行函数,返回结果和错误 自动处理 cancel 调用,并监听 context 超时

使用示例:

result, err := contextx.WithTimeoutValue(2*time.Second, func(ctx context.Context) (int, error) {
    return repo.GetCount(ctx)
})

func WithValue

func WithValue(ctx context.Context, key, value interface{}) context.Context

WithValue 为标准 context.Context 设置值

Types

type Context

type Context struct {
	context.Context
	// contains filtered or unexported fields
}

Context 是一个自定义的上下文,支持多个值的存储

func MergeContext

func MergeContext(ctxs ...context.Context) *Context

MergeContext 合并多个上下文为一个 Context

func NewContext

func NewContext() *Context

NewContext 创建一个新的 Context(使用默认配置)

func NewContextWithTimeout

func NewContextWithTimeout(timeout time.Duration) *Context

NewContextWithTimeout 创建一个带有超时的 Context(便捷方法)

func NewContextWithValue

func NewContextWithValue(key, val interface{}) *Context

NewContextWithValue 在上下文中设置值并返回新的 Context(便捷方法)

func (*Context) Cancel

func (c *Context) Cancel()

Cancel 取消上下文

func (*Context) Clone

func (c *Context) Clone() *Context

Clone 克隆上下文(深拷贝)

func (*Context) Deadline

func (c *Context) Deadline() (deadline time.Time, ok bool)

Deadline 返回上下文的截止时间

func (*Context) GetAllMetadata

func (c *Context) GetAllMetadata() map[string]string

GetAllMetadata 获取所有元数据

func (*Context) GetBool

func (c *Context) GetBool(key interface{}) bool

GetBool 获取布尔值(便捷方法)

func (*Context) GetDuration

func (c *Context) GetDuration(key interface{}) time.Duration

GetDuration 获取时间间隔(便捷方法)

func (*Context) GetFloat32

func (c *Context) GetFloat32(key interface{}) float32

GetFloat32 获取浮点数值(便捷方法)

func (*Context) GetFloat64

func (c *Context) GetFloat64(key interface{}) float64

GetFloat64 获取浮点数值(便捷方法)

func (*Context) GetInt

func (c *Context) GetInt(key interface{}) int

GetInt 获取整数值(便捷方法)

func (*Context) GetInt8

func (c *Context) GetInt8(key interface{}) int8

GetInt8 获取 int8 值(便捷方法)

func (*Context) GetInt16

func (c *Context) GetInt16(key interface{}) int16

GetInt16 获取 int16 值(便捷方法)

func (*Context) GetInt32

func (c *Context) GetInt32(key interface{}) int32

GetInt32 获取 int32 值(便捷方法)

func (*Context) GetInt64

func (c *Context) GetInt64(key interface{}) int64

GetInt64 获取 int64 值(便捷方法)

func (*Context) GetIntSlice

func (c *Context) GetIntSlice(key interface{}) []int

GetIntSlice 获取整数切片

func (*Context) GetMap

func (c *Context) GetMap(key interface{}) map[string]interface{}

GetMap 获取 map

func (*Context) GetMetadata

func (c *Context) GetMetadata(key string) string

GetMetadata 获取元数据

func (*Context) GetRune

func (c *Context) GetRune(key interface{}) rune

GetRune 获取 rune 值(便捷方法)

func (*Context) GetString

func (c *Context) GetString(key interface{}) string

GetString 获取字符串值(便捷方法)

func (*Context) GetStringSlice

func (c *Context) GetStringSlice(key interface{}) []string

GetStringSlice 获取字符串切片

func (*Context) GetTime

func (c *Context) GetTime(key interface{}) time.Time

GetTime 获取时间值(便捷方法)

func (*Context) GetUint

func (c *Context) GetUint(key interface{}) uint

GetUint 获取无符号整数值(便捷方法)

func (*Context) GetUint8

func (c *Context) GetUint8(key interface{}) uint8

GetUint8 获取 uint8 值(便捷方法)

func (*Context) GetUint16

func (c *Context) GetUint16(key interface{}) uint16

GetUint16 获取 uint16 值(便捷方法)

func (*Context) GetUint32

func (c *Context) GetUint32(key interface{}) uint32

GetUint32 获取 uint32 值(便捷方法)

func (*Context) GetUint64

func (c *Context) GetUint64(key interface{}) uint64

GetUint64 获取 uint64 值(便捷方法)

func (*Context) IsExpired

func (c *Context) IsExpired() bool

IsExpired 检查是否超时

func (*Context) MustValue

func (c *Context) MustValue(key interface{}) interface{}

MustValue 获取值,不存在则 panic

func (*Context) Range

func (c *Context) Range(f func(key, value interface{}) bool)

Range 遍历所有键值对(类似 sync.Map.Range)

func (*Context) Remove

func (c *Context) Remove(key interface{}) *Context

Remove 删除指定键的键值对,支持链式调用

func (*Context) SafeGetStringSlice

func (c *Context) SafeGetStringSlice(key interface{}) []string

SafeGetStringSlice 安全获取字符串切片(别名方法,兼容旧代码)

func (*Context) SetBatch

func (c *Context) SetBatch(kvs map[interface{}]interface{}) *Context

SetBatch 批量设置键值对,支持链式调用

func (*Context) SetDeadline

func (c *Context) SetDeadline(timeout time.Duration) *Context

SetDeadline 设置自定义超时时间

func (*Context) SetMetadataBatch

func (c *Context) SetMetadataBatch(kvs map[string]string) *Context

SetMetadataBatch 批量设置元数据

func (*Context) String

func (c *Context) String() string

String 返回上下文的字符串表示

func (*Context) Value

func (c *Context) Value(key interface{}) interface{}

Value 获取指定键的值 加锁写在原地,不用闭包式的 syncx.WithRLockReturnValue

那个 helper 收的是接口加一个闭包,闭包捕获 c 与 key本函数的闭包体里还要调 c.Context.Value,体量超过内联阈值,于是 helper 没被内联、闭包只能堆分配—— 每次取值一次分配

这不是「闭包式加锁一定会分配」:闭包体小到 helper 能被内联时,编译器会把闭包 留在栈上同样写法在别处可能是零分配,所以不能照着改一片,只能按实测逐个处理 这一处是用内存 profile 定位出来的:它占了 matcher 匹配路径全部分配的 46.6%

[EN] The lock is taken inline rather than through the closure-taking syncx.WithRLockReturnValue helper, which takes an interface and a closure capturing c and key. This function's closure also calls c.Context.Value, which puts it over the inlining threshold, so the helper is not inlined and the closure must be heap-allocated — one allocation per lookup. This is not a general rule that closure-style locking allocates: where the body is small enough for the helper to inline, the compiler keeps the closure on the stack, so the same spelling is allocation-free elsewhere and these cannot be changed wholesale, only where measured. A memory profile located this one: it was 46.6% of all allocations on the matcher's match path

func (*Context) Values

func (c *Context) Values() map[interface{}]interface{}

Values 返回当前上下文中所有的键值对

func (*Context) WithByteSlice

func (c *Context) WithByteSlice(key interface{}, value []byte) *Context

WithByteSlice 处理字节切片的存储,支持链式调用

func (*Context) WithCancel

func (c *Context) WithCancel() *Context

WithCancel 添加取消功能

func (*Context) WithDeadline

func (c *Context) WithDeadline(deadline time.Time) *Context

WithDeadline 设置绝对截止时间

func (*Context) WithMetadata

func (c *Context) WithMetadata(key, value string) *Context

WithMetadata 设置元数据(并发安全)

func (*Context) WithParent

func (c *Context) WithParent(parent context.Context) *Context

WithParent 设置父上下文 若已设置 deadline 或 cancel,会在新父上下文上重新应用,避免覆盖超时/取消行为

func (*Context) WithPool

func (c *Context) WithPool(pool *syncx.LimitedPool) *Context

WithPool 设置对象池

func (*Context) WithTimeout

func (c *Context) WithTimeout(timeout time.Duration) *Context

WithTimeout 设置超时时间

func (*Context) WithValue

func (c *Context) WithValue(key, value interface{}) *Context

WithValue 设置指定键的值,支持链式调用

type Marshaler

type Marshaler interface {
	Marshal(v any) (string, error)
	Unmarshal(data string, v any) error
}

Marshaler 定义序列化接口

type MetadataAdapter

type MetadataAdapter interface {
	// Set 将字符串值写入 context metadata
	Set(ctx context.Context, key, value string) context.Context

	// Get 从 context metadata 获取字符串值
	Get(ctx context.Context, key string) (string, bool)

	// Append 向现有 context 追加 metadata(不覆盖已有的)
	Append(ctx context.Context, key, value string) context.Context
}

MetadataAdapter 定义 metadata 操作的适配器接口 使用适配器模式,让不同的实现(gRPC、HTTP、自定义)可以灵活接入

type MetadataManager

type MetadataManager struct {
	// contains filtered or unexported fields
}

MetadataManager 封装 adapter 和 marshaler,提供简洁的 API

func NewMetadataManager

func NewMetadataManager(adapter MetadataAdapter, marshaler Marshaler) *MetadataManager

NewMetadataManager 创建 metadata 管理器

func (*MetadataManager) Append

func (m *MetadataManager) Append(ctx context.Context, key string, value any) (context.Context, error)

Append 向现有 context 追加 metadata

func (*MetadataManager) Get

func (m *MetadataManager) Get(ctx context.Context, key string, result any) error

Get 从 context metadata 获取数据(泛型方法)

func (*MetadataManager) GetOrDefault

func (m *MetadataManager) GetOrDefault(ctx context.Context, key string, defaultValue any) any

GetOrDefault 获取数据,如果不存在则返回默认值(泛型方法)

func (*MetadataManager) Set

func (m *MetadataManager) Set(ctx context.Context, key string, value any) (context.Context, error)

Set 将任意类型的数据写入 context metadata(泛型方法)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL