Timeout Implementation
Context-Based Timeout Strategies
Using Context with Timeout
func timeoutWithContext() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
resultChan := make(chan string)
go func() {
time.Sleep(3 * time.Second)
resultChan <- "Task completed"
}()
select {
case result := <-resultChan:
fmt.Println(result)
case <-ctx.Done():
fmt.Println("Task timed out")
}
}
Timeout Implementation Techniques
Technique |
Pros |
Cons |
Context Timeout |
Flexible, standard library support |
Slightly complex setup |
Channel-based Timeout |
Simple implementation |
Limited to basic scenarios |
Select Statement |
Non-blocking |
Requires careful channel management |
Advanced Timeout Patterns
graph TD
A[Timeout Request] --> B{Select Statement}
B -->|Channel Receive| C[Process Result]
B -->|Timeout Channel| D[Handle Timeout]
B -->|Context Cancellation| E[Graceful Shutdown]
Practical Timeout Example with Network Operation
func fetchDataWithTimeout(url string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
Best Practices
- Always use
defer cancel()
with context
- Set reasonable timeout durations
- Handle both successful and timeout scenarios
- Clean up resources in timeout handlers
- Timeouts add minimal overhead
- Use sparingly for critical operations
- Monitor and tune timeout values
LabEx recommends practicing these timeout techniques to build robust and responsive Go applications.