Repository navigation
Concurrency EN
English | 简体中文
A Client is safe for concurrent use by any number of goroutines. It holds no per-request state, its configuration is read-only after construction, and the underlying http.Client pools connections (MaxIdleConnsPerHost: 100).
Create one client, share it, and pass a context.Context per call for cancellation and deadlines:
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()Unbounded goroutines mean unbounded in-flight requests. Use a semaphore or a worker pool:
sem := make(chan struct{}, 16) // at most 16 calls in flight
var wg sync.WaitGroup
for _, ticket := range tickets {
wg.Add(1)
go func(ticket string) {
defer wg.Done()
sem <- struct{}{}
defer func() { <-sem }()
response, err := client.SystemOne(ctx, ticket, questions)
// ...
}(ticket)
}
wg.Wait()jobs := make(chan Ticket)
var wg sync.WaitGroup
for range runtime.NumCPU() {
wg.Add(1)
go func() {
defer wg.Done()
for ticket := range jobs {
// one SystemOne call per ticket
}
}()
}Every call takes a context, so cancelling it aborts the request immediately:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
response, err := client.SystemOne(ctx, state, questions)A cancelled or expired context is never retried: the SDK returns the failure immediately instead of extending a call the caller has already given up on. See Retry Policy.
Close releases idle connections. Call it once when the application shuts down; it is idempotent, and subsequent calls return the first call's error.
- 指南
- Guides