refactor: 将 WithAffinity 重命名为 WithSticky,文件 affinity.go → sticky.go

This commit is contained in:
2026-05-08 11:37:34 +08:00
parent 3d293699e9
commit a3cf983b39
4 changed files with 34 additions and 34 deletions

View File

@@ -188,7 +188,7 @@ def slow_compute(n: int) -> int:
## Session 亲和路由 ## Session 亲和路由
默认情况下,每次 `Invoke` 通过轮询分配 worker 进程。当多次调用需要共享同一 Python 进程的状态时,可以使用 Session 或 WithAffinity 将调用固定到同一进程。 默认情况下,每次 `Invoke` 通过轮询分配 worker 进程。当多次调用需要共享同一 Python 进程的状态时,可以使用 Session 或 WithSticky 将调用固定到同一进程。
### NewSession ### NewSession
@@ -223,13 +223,13 @@ def step(session_id: str, delta: int) -> int:
> `NewSession` 不拥有底层 pool 的生命周期,调用 `session.Close()` 是空操作,只需关闭原始 pool。 > `NewSession` 不拥有底层 pool 的生命周期,调用 `session.Close()` 是空操作,只需关闭原始 pool。
### WithAffinity ### WithSticky
`WithAffinity` 将亲和键写入 ctx相同 key 通过哈希稳定路由到同一 worker无需持有 session 对象: `WithSticky` 将亲和键写入 ctx相同 key 通过哈希稳定路由到同一 worker无需持有 session 对象:
```go ```go
// 每次调用前附加 key相同 key 始终走同一 worker // 每次调用前附加 key相同 key 始终走同一 worker
ctx = gobridge.WithAffinity(ctx, "user-42") ctx = gobridge.WithSticky(ctx, "user-42")
gobridge.Invoke(ctx, pool, "method_a", ...) gobridge.Invoke(ctx, pool, "method_a", ...)
gobridge.Invoke(ctx, pool, "method_b", ...) gobridge.Invoke(ctx, pool, "method_b", ...)
``` ```
@@ -262,7 +262,7 @@ gobridge.Invoke(ctx, sessB, "increment", 99) // worker 0: counter = 99独立
### 两种方式对比 ### 两种方式对比
| | `NewSession` | `WithAffinity` | | | `NewSession` | `WithSticky` |
|---|---|---| |---|---|---|
| 路由方式 | 创建时轮询确定 worker | 按 key 哈希确定 worker | | 路由方式 | 创建时轮询确定 worker | 按 key 哈希确定 worker |
| 适用场景 | 显式会话管理 | 按自然键(用户 ID 等)路由 | | 适用场景 | 显式会话管理 | 按自然键(用户 ID 等)路由 |

View File

@@ -1,26 +0,0 @@
package gobridge
import (
"context"
"hash/fnv"
)
type affinityKey struct{} // 用户提供的字符串 keyacquire 时 hash 到 worker 下标
// WithAffinity 将亲和键写入 ctx相同 key 始终路由到同一 worker 进程。
//
// ctx = gobridge.WithAffinity(ctx, "user-42")
// gobridge.Invoke(ctx, pool, "method", ...) // 同 key 始终走同一进程
func WithAffinity(ctx context.Context, key string) context.Context {
return context.WithValue(ctx, affinityKey{}, key)
}
// workerIndexFor 根据 ctx 计算应使用的 worker 下标,无亲和键时返回 -1交由轮询
func workerIndexFor(ctx context.Context, n int) int {
if key, ok := ctx.Value(affinityKey{}).(string); ok && key != "" {
h := fnv.New32a()
h.Write([]byte(key))
return int(h.Sum32()) % n
}
return -1
}

View File

@@ -235,13 +235,13 @@ func demoSession(ctx context.Context, script string) {
r, _ = gobridge.Invoke[string](ctx, sessA, "global_get") r, _ = gobridge.Invoke[string](ctx, sessA, "global_get")
fmt.Println("sessA get:", r) // worker 1 counter = 15不受 sessB 影响) fmt.Println("sessA get:", r) // worker 1 counter = 15不受 sessB 影响)
// ── WithAffinity相同 key 跨调用始终路由同一 worker ──────────────────── // ── WithSticky相同 key 跨调用始终路由同一 worker ────────────────────
fmt.Println() fmt.Println()
for i := range 4 { for i := range 4 {
affinityCtx := gobridge.WithAffinity(ctx, "sticky-key") affinityCtx := gobridge.WithSticky(ctx, "sticky-key")
msg, _ := gobridge.Invoke[string](affinityCtx, pool, "session_init", msg, _ := gobridge.Invoke[string](affinityCtx, pool, "session_init",
fmt.Sprintf("aff-%d", i), i) fmt.Sprintf("aff-%d", i), i)
fmt.Printf("WithAffinity(sticky-key) #%d → %s\n", i, msg) fmt.Printf("WithSticky(sticky-key) #%d → %s\n", i, msg)
} }
// ── 对照组:不带亲和,轮询分配给两个 worker ───────────────────────────── // ── 对照组:不带亲和,轮询分配给两个 worker ─────────────────────────────

26
sticky.go Normal file
View File

@@ -0,0 +1,26 @@
package gobridge
import (
"context"
"hash/fnv"
)
type stickyKey struct{} // 用户提供的字符串 keyacquire 时 hash 到 worker 下标
// WithSticky 将粘性键写入 ctx相同 key 始终路由到同一 worker 进程。
//
// ctx = gobridge.WithSticky(ctx, "user-42")
// gobridge.Invoke(ctx, pool, "method", ...) // 同 key 始终走同一进程
func WithSticky(ctx context.Context, key string) context.Context {
return context.WithValue(ctx, stickyKey{}, key)
}
// workerIndexFor 根据 ctx 计算应使用的 worker 下标,无粘性键时返回 -1交由轮询
func workerIndexFor(ctx context.Context, n int) int {
if key, ok := ctx.Value(stickyKey{}).(string); ok && key != "" {
h := fnv.New32a()
h.Write([]byte(key))
return int(h.Sum32()) % n
}
return -1
}