Advanced Techniques
Context Value Passing
Storing and Retrieving Custom Values
type RequestID string
func withRequestID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, RequestID("request-id"), id)
}
func getRequestID(ctx context.Context) string {
if val := ctx.Value(RequestID("request-id")); val != nil {
return val.(string)
}
return ""
}
Concurrent Context Management
Parallel Operation with Context
func parallelTasks(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
results := make(chan string, 3)
tasks := []func(context.Context){}
for _, task := range tasks {
go func(t func(context.Context)) {
t(ctx)
}(task)
}
select {
case <-ctx.Done():
return ctx.Err()
case result := <-results:
return processResult(result)
}
}
Context Propagation Patterns
Pattern |
Description |
Use Case |
Request Tracing |
Pass trace IDs |
Distributed systems |
Authentication |
Carry user credentials |
Microservice authorization |
Logging Context |
Attach metadata |
Structured logging |
Context in Middleware Design
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), "user", authenticateUser())
next.ServeHTTP(w, r.WithContext(ctx))
}
}
Context Cancellation Strategies
flowchart TD
A[Start Operation] --> B{Context Active?}
B -->|Yes| C[Continue Processing]
B -->|No| D[Graceful Shutdown]
C --> E{Check Cancellation}
E -->|Cancelled| D
E -->|Continue| C
Advanced Error Handling
func complexOperation(ctx context.Context) error {
select {
case <-ctx.Done():
switch ctx.Err() {
case context.Canceled:
return fmt.Errorf("operation manually cancelled")
case context.DeadlineExceeded:
return fmt.Errorf("operation timed out")
}
default:
// Normal processing logic
}
return nil
}
Context in Generative Patterns
func processStream[T any](
ctx context.Context,
input <-chan T,
process func(T) error
) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
case item, ok := <-input:
if !ok {
return nil
}
if err := process(item); err != nil {
return err
}
}
}
}
Best Practices for Advanced Context Usage
- Use type-safe context values
- Implement proper cancellation mechanisms
- Avoid over-complicating context propagation
- Always consider performance implications
At LabEx, we recommend mastering these advanced context techniques to build sophisticated, responsive Go applications that handle complex concurrency scenarios efficiently.