Skip to content
This repository was archived by the owner on Jun 12, 2026. It is now read-only.

Commit 2df919a

Browse files
lvan100lianghuan
authored andcommitted
improve documentation
1 parent 77b70a4 commit 2df919a

22 files changed

Lines changed: 788 additions & 306 deletions
File renamed without changes.

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Set up Go
2525
uses: actions/setup-go@v6.3.0
2626
with:
27-
go-version: '1.25'
27+
go-version: '1.26'
2828

2929
- name: Install golangci-lint
3030
uses: golangci/golangci-lint-action@v9.2.0

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Set up Go
2525
uses: actions/setup-go@v6.3.0
2626
with:
27-
go-version: '1.25'
27+
go-version: '1.26'
2828

2929
- name: Install dependencies
3030
run: go mod download
@@ -33,7 +33,7 @@ jobs:
3333
run: go test -count=1 -coverprofile=coverage.txt ./...
3434

3535
- name: Upload results to Codecov
36-
uses: codecov/codecov-action@v5.5.2
36+
uses: codecov/codecov-action@v6.0.0
3737
with:
3838
token: ${{ secrets.CODECOV_TOKEN }}
3939
slug: go-spring/stdlib

README.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,6 @@
44

55
`stdlib` is a collection of independent utility modules written in Go.
66

7-
## Module Overview
8-
9-
### `errutil` – Structured Error Handling Utilities
10-
11-
For more details, see [errutil/README.md](errutil/README.md).
12-
13-
### `flatten` – Hierarchical Data Flattening Utilities
14-
15-
For more details, see [flatten/README.md](flatten/README.md).
16-
17-
### `iterutil` – Iteration Utilities
18-
19-
For more details, see [iterutil/README.md](iterutil/README.md).
20-
21-
### `testing` – Testing Assertion Toolkit
22-
23-
For more details, see [testing/README.md](testing/README.md).
24-
257
## License
268

279
Apache License 2.0

README_CN.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,6 @@
44

55
`stdlib` 是一个包含多个独立 Go 语言工具模块的集合库。
66

7-
## 模块概览
8-
9-
### `errutil` - 结构化错误处理工具
10-
11-
更多信息请参见 [errutil/README.md](errutil/README.md)
12-
13-
### `flatten` - 层级数据扁平化处理工具
14-
15-
更多信息请参见 [flatten/README.md](flatten/README.md)
16-
17-
### `iterutil` - 迭代工具
18-
19-
更多信息请参见 [iterutil/README.md](iterutil/README.md)
20-
21-
### `testing` - 测试断言工具包
22-
23-
更多信息请参见 [testing/README.md](testing/README.md)
24-
257
## 许可证
268

279
Apache License 2.0

check.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ if ! command_exists modernize; then
6363
install_modernize
6464
fi
6565

66-
# Find fmt.Errorf and errors.New function calls, excluding vendor directory
67-
find . -type f -name '*.go' ! -path './vendor/*' -exec grep -Hn 'fmt\.Errorf' {} \;
68-
find . -type f -name '*.go' ! -path './vendor/*' -exec grep -Hn 'errors\.New' {} \;
66+
# Find fmt.Errorf and errors.New function calls, excluding vendor & errutil directory
67+
find . -type f -name '*.go' ! -path './vendor/*' ! -path './errutil/*' -exec grep -Hn 'fmt\.Errorf' {} \;
68+
find . -type f -name '*.go' ! -path './vendor/*' ! -path './errutil/*' -exec grep -Hn 'errors\.New' {} \;
6969

7070
print_separator
7171
echo "Step 1/3: Running go fix..."

ctxcache/README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# ctxcache
2+
3+
[English](README.md) | [中文](README_CN.md)
4+
5+
## Introduction
6+
7+
`ctxcache` is a strongly-typed, context-scoped cache package designed for request-scoped data.
8+
9+
`ctxcache` attaches a concurrency-safe, write-once key-value store to `context.Context`, allowing values to be
10+
implicitly propagated across call boundaries without polluting function signatures.
11+
12+
## Features
13+
14+
- **Strong Type Safety**: Uses generics combining string names and Go type parameters as key identifiers, ensuring type
15+
safety and preventing collisions between values of different types—even if they share the same string identifier
16+
- **Concurrency Safe**: Internally uses mutex-protected maps, supporting concurrent access
17+
- **Write-Once Semantics**: Each key can be assigned exactly once, then read multiple times until the cache is cleared
18+
- **Context Lifecycle**: Cache lifecycle is explicitly controlled by the cancel function returned from `Init`
19+
- **Request Scope Isolation**: Cache is attached to context, naturally supporting request-level data isolation
20+
21+
## Main Functions
22+
23+
### Initialize Cache
24+
25+
Use the `Init` function to attach a cache to a context:
26+
27+
```go
28+
ctx, cancel := ctxcache.Init(ctx)
29+
defer cancel() // Clean up cache at request boundary
30+
```
31+
32+
`Init` is idempotent: repeated calls with the same context return the original context and a no-op cancel function.
33+
34+
### Set Values
35+
36+
Use the `Set` function to assign a value to a key:
37+
38+
```go
39+
err := ctxcache.Set(ctx, "user", userInfo)
40+
if err != nil {
41+
// handle error
42+
}
43+
```
44+
45+
Each key can only be set once. Repeated attempts return an `ErrKeyAlreadySet` error.
46+
47+
### Get Values
48+
49+
Use the `Get` function to retrieve a value:
50+
51+
```go
52+
value, err := ctxcache.Get[UserType](ctx, "user")
53+
if err != nil {
54+
// handle error
55+
}
56+
```
57+
58+
`Get` is a generic function that requires specifying a type parameter to ensure type safety.
59+
60+
### Clear Cache
61+
62+
Calling the cancel function returned by `Init` clears all cached values:
63+
64+
```go
65+
cancel() // Clear cache and make it permanently unusable
66+
```
67+
68+
Once cleared, subsequent `Get` or `Set` operations will return `ErrCacheAlreadyCleared` error.
69+
70+
## Error Types
71+
72+
The package defines the following error types:
73+
74+
- `ErrCacheNotInitialized`: Cache is not initialized
75+
- `ErrCacheAlreadyCleared`: Cache has already been cleared
76+
- `ErrKeyNotSet`: Key is not set
77+
- `ErrKeyAlreadySet`: Key is already set
78+
79+
## Typical Use Cases
80+
81+
1. **HTTP Middleware**: Initialize cache at request entry point and clean up at exit
82+
2. **Authenticated User Info**: Store authenticated user objects
83+
3. **Permission Data**: Pass user permission lists
84+
4. **Trace Metadata**: Carry trace context information
85+
5. **Computed Intermediates**: Share computed intermediate values across call chains
86+
87+
## Example Usage
88+
89+
```go
90+
package main
91+
92+
import (
93+
"context"
94+
"fmt"
95+
"github.com/go-spring/stdlib/ctxcache"
96+
)
97+
98+
type User struct {
99+
ID int
100+
Name string
101+
}
102+
103+
func main() {
104+
ctx := context.Background()
105+
106+
// Initialize cache
107+
ctx, cancel := ctxcache.Init(ctx)
108+
defer cancel()
109+
110+
// Set user info
111+
user := User{ID: 1, Name: "Alice"}
112+
if err := ctxcache.Set(ctx, "user", user); err != nil {
113+
panic(err)
114+
}
115+
116+
// Get user info in downstream code
117+
retrievedUser, err := ctxcache.Get[User](ctx, "user")
118+
if err != nil {
119+
panic(err)
120+
}
121+
122+
fmt.Printf("User: %+v\n", retrievedUser)
123+
}
124+
```
125+
126+
## Notes
127+
128+
- `ctxcache` is not a general-purpose cache. It is designed for structured, short-lived, in-process context data
129+
- Each key can only be assigned once. This is intentional design to ensure data immutability
130+
- The cancel function should be called at request boundaries to ensure request-scoped data is properly cleaned up
131+
- Once cleared, the cache becomes permanently unusable and should not be used again

ctxcache/README_CN.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# ctxcache
2+
3+
[English](README.md) | [中文](README_CN.md)
4+
5+
## 简介
6+
7+
`ctxcache` 是一个强类型的、上下文作用域的缓存包,专为请求范围(request-scoped)的数据而设计。
8+
9+
`ctxcache` 将并发安全、写一次(write-once)的键值存储附加到 `context.Context` 上,允许值在调用边界之间隐式传播,而无需污染函数签名。
10+
11+
## 特性
12+
13+
- **强类型安全**:通过泛型结合字符串名称和 Go 类型参数作为键标识,确保类型安全,防止不同类型但相同字符串标识符的值发生冲突
14+
- **并发安全**:内部使用互斥锁保护映射,支持并发访问
15+
- **写一次语义**:每个键只能被赋值一次,之后可多次读取,直到缓存被清除
16+
- **上下文生命周期**:缓存的生命周期由 `Init` 返回的取消函数显式控制
17+
- **请求范围隔离**:缓存附加到上下文,天然支持请求级别的数据隔离
18+
19+
## 主要功能
20+
21+
### 初始化缓存
22+
23+
使用 `Init` 函数将缓存附加到上下文:
24+
25+
```go
26+
ctx, cancel := ctxcache.Init(ctx)
27+
defer cancel() // 在请求边界处清理缓存
28+
```
29+
30+
`Init` 是幂等的:对同一上下文重复调用会返回原始上下文和无操作的取消函数。
31+
32+
### 设置值
33+
34+
使用 `Set` 函数为键赋值:
35+
36+
```go
37+
err := ctxcache.Set(ctx, "user", userInfo)
38+
if err != nil {
39+
// 处理错误
40+
}
41+
```
42+
43+
每个键只能设置一次,重复设置会返回 `ErrKeyAlreadySet` 错误。
44+
45+
### 获取值
46+
47+
使用 `Get` 函数检索值:
48+
49+
```go
50+
value, err := ctxcache.Get[UserType](ctx, "user")
51+
if err != nil {
52+
// 处理错误
53+
}
54+
```
55+
56+
`Get` 是泛型函数,需要指定类型参数来确保类型安全。
57+
58+
### 清除缓存
59+
60+
调用 `Init` 返回的取消函数会清除所有缓存值:
61+
62+
```go
63+
cancel() // 清除缓存并使其永久不可用
64+
```
65+
66+
缓存一旦清除,后续的 `Get``Set` 操作都会返回 `ErrCacheAlreadyCleared` 错误。
67+
68+
## 错误类型
69+
70+
包中定义了以下错误类型:
71+
72+
- `ErrCacheNotInitialized`: 缓存未初始化
73+
- `ErrCacheAlreadyCleared`: 缓存已被清除
74+
- `ErrKeyNotSet`: 键未设置
75+
- `ErrKeyAlreadySet`: 键已被设置
76+
77+
## 典型使用场景
78+
79+
1. **HTTP 中间件**:在请求入口处初始化缓存,在出口处清理
80+
2. **认证用户信息**:存储经过身份验证的用户对象
81+
3. **权限数据**:传递用户的权限列表
82+
4. **追踪元数据**:携带链路追踪相关的上下文信息
83+
5. **计算中间结果**:在调用链中共享已计算的中间值
84+
85+
## 使用示例
86+
87+
```go
88+
package main
89+
90+
import (
91+
"context"
92+
"fmt"
93+
"github.com/go-spring/stdlib/ctxcache"
94+
)
95+
96+
type User struct {
97+
ID int
98+
Name string
99+
}
100+
101+
func main() {
102+
ctx := context.Background()
103+
104+
// 初始化缓存
105+
ctx, cancel := ctxcache.Init(ctx)
106+
defer cancel()
107+
108+
// 设置用户信息
109+
user := User{ID: 1, Name: "Alice"}
110+
if err := ctxcache.Set(ctx, "user", user); err != nil {
111+
panic(err)
112+
}
113+
114+
// 在下游代码中获取用户信息
115+
retrievedUser, err := ctxcache.Get[User](ctx, "user")
116+
if err != nil {
117+
panic(err)
118+
}
119+
120+
fmt.Printf("User: %+v\n", retrievedUser)
121+
}
122+
```
123+
124+
## 注意事项
125+
126+
- `ctxcache` 不是通用缓存,专为结构化、短生命周期、进程内的上下文数据设计
127+
- 每个键只能赋值一次,这是有意为之的设计,确保数据的不可变性
128+
- 取消函数应在请求边界处调用,以确保请求范围的数据被正确清理
129+
- 缓存清除后永久不可用,不应再对其进行任何操作

ctxcache/ctxcache.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,19 @@ func Get[T any](ctx context.Context, key string) (T, error) {
151151
k := TypedKey[T]{Key: key}
152152
cache, ok := getCache(ctx)
153153
if !ok {
154-
return zero, errutil.Explain(ErrCacheNotInitialized, "%s", k)
154+
return zero, errutil.Explain(ErrCacheNotInitialized, "ctxcache: get %s error", k)
155155
}
156156

157157
cache.mutex.Lock()
158158
defer cache.mutex.Unlock()
159159

160160
if cache.cleared {
161-
return zero, errutil.Explain(ErrCacheAlreadyCleared, "%s", k)
161+
return zero, errutil.Explain(ErrCacheAlreadyCleared, "ctxcache: get %s error", k)
162162
}
163163

164164
v, ok := cache.values[k]
165165
if !ok {
166-
return zero, errutil.Explain(ErrKeyNotSet, "%s", k)
166+
return zero, errutil.Explain(ErrKeyNotSet, "ctxcache: get %s error", k)
167167
}
168168

169169
return v.(T), nil
@@ -181,18 +181,18 @@ func Set[T any](ctx context.Context, key string, value T) error {
181181
k := TypedKey[T]{Key: key}
182182
cache, ok := getCache(ctx)
183183
if !ok {
184-
return errutil.Explain(ErrCacheNotInitialized, "%s", k)
184+
return errutil.Explain(ErrCacheNotInitialized, "ctxcache: set %s error", k)
185185
}
186186

187187
cache.mutex.Lock()
188188
defer cache.mutex.Unlock()
189189

190190
if cache.cleared {
191-
return errutil.Explain(ErrCacheAlreadyCleared, "%s", k)
191+
return errutil.Explain(ErrCacheAlreadyCleared, "ctxcache: set %s error", k)
192192
}
193193

194194
if _, ok = cache.values[k]; ok {
195-
return errutil.Explain(ErrKeyAlreadySet, "%s", k)
195+
return errutil.Explain(ErrKeyAlreadySet, "ctxcache: set %s error", k)
196196
}
197197

198198
cache.values[k] = value

0 commit comments

Comments
 (0)