Home > Article > Backend Development > How Can I Gracefully Cancel Goroutines After a Specified Time Limit in Go?
Canceling Goroutines after a Time Limit
In load testing scenarios, controlling the execution duration of Goroutines is crucial. Here's an effective approach to achieve this.
Consider the following code snippet that manages HTTP requests in Goroutines:
func attack(cfg AttackConfig) { // some code ... var ar attackResponse ch := make(chan uint8, 8) go func() { time.Sleep(cfg.Duration * time.Second) ch <- CALL_TIME_RAN_OUT }() for { if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 { go httpPost(cfg, &ar, ch) } switch <-ch { // some other cases ... case CALL_TIME_RAN_OUT: fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration) return } } }
However, Goroutines from httpPost() continue running after the specified cfg.Duration has elapsed.
To address this issue, you can leverage Go's context package. By passing a context.Context object to your Goroutines, you can cancel those Goroutines when the specified timeout is reached.
Here's a revised version of your code using the context package:
import ( "context" "fmt" "golang.org/x/net/context" "time" ) func attack(cfg AttackConfig) { // some code ... var ar attackResponse // Define a timeout context ctx, cancel := context.WithTimeout(context.Background(), cfg.Duration*time.Second) defer cancel() go func() { time.Sleep(cfg.Duration * time.Second) cancel() }() for { if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 { go httpPost(ctx, cfg, &ar) } select { // some other cases ... case <-ctx.Done(): fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration) return } } } func httpPost(ctx context.Context, cfg AttackConfig, a *attackResponse) { // some code here to create HTTP client ... for { // some code to make HTTP call ... select { case <-ctx.Done(): return default: } } }
With this modification, when the specified cfg.Duration expires, the ctx.Done() channel is closed, signaling the cancellation of the httpPost() Goroutines, which will then return.
The above is the detailed content of How Can I Gracefully Cancel Goroutines After a Specified Time Limit in Go?. For more information, please follow other related articles on the PHP Chinese website!