Repository navigation
Concurrency
sungaowei edited this page Oct 16, 2026
·
2 revisions
English Version | 简体中文
typesafe.Client 是并发安全的,可由任意数量的 Goroutine 同时复用。
客户端内部不保存任何特定请求的可变状态,初始化完成后其配置均为只读,底层的 http.Client 会自动管理高效的 HTTP 连接池(MaxIdleConnsPerHost: 100)。
推荐在整个应用程序生命周期中只创建一个 Client 实例并全局共享,每次请求调用时传入独立的 context.Context 控制生命周期:
var wg sync.WaitGroup
for _, ticket := range tickets {
wg.Add(1)
go func(ticket string) {
defer wg.Done()
response, err := client.SystemOne(ctx, ticket, questions)
if err != nil {
log.Printf("%s 评估失败: %v", ticket, err)
return
}
fmt.Printf("%s -> %s\n", ticket, response.Choices()["category"].Choice)
}(ticket)
}
wg.Wait()无限制地为海量任务启动 Goroutine 会瞬间发起成百上千个并发网络连接,可能迅速耗尽系统文件描述符或触发服务端的速率限制。 推荐使用带缓冲的通道作为信号量,或采用工作协程池(Worker Pool)模式:
sem := make(chan struct{}, 16) // 最多允许 16 个并发请求在传输中
var wg sync.WaitGroup
for _, ticket := range tickets {
wg.Add(1)
go func(t string) {
defer wg.Done()
sem <- struct{}{} // 获取令牌
defer func() { <-sem }() // 释放令牌
response, err := client.SystemOne(ctx, t, questions)
// 处理结果...
}(ticket)
}
wg.Wait()jobs := make(chan Ticket, 100)
var wg sync.WaitGroup
// 启动与 CPU 核心数相当的常驻工作 Goroutine
for range runtime.NumCPU() {
wg.Add(1)
go func() {
defer wg.Done()
for ticket := range jobs {
response, err := client.SystemOne(ctx, ticket, questions)
// 处理工单...
}
}()
}
// 投递任务
for _, t := range tickets {
jobs <- t
}
close(jobs)
wg.Wait()每个 SDK 方法均接受 context.Context 参数。只要取消 Context 或达到 Deadline 超时,当前网络请求将被立即中断:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
response, err := client.SystemOne(ctx, state, questions)Important
被主动取消或超时的上下文绝不会触发重试:SDK 会立即返回失败,而不会在调用方已经放弃该请求时继续浪费时间重试。参见 重试策略 (Retry Policy)。
client.Close() 会释放底层空闲连接池所占用的资源。在程序准备优雅退出时调用一次即可。
该方法是幂等安全的,重复调用将直接返回第一次调用时的结果。
- 指南
- Guides