Utilisation pratique du contexte (Context)
Scénarios réels d'utilisation du contexte (Context)
Le contexte (context) est essentiel dans divers scénarios pratiques de programmation, en fournissant des mécanismes solides pour gérer les opérations concurrentes et les cycles de vie des requêtes.
Communication entre microservices
Contexte (Context) dans les requêtes inter-services
func fetchUserData(ctx context.Context, userID string) (*User, error) {
// Create request with context
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("/users/%s", userID), nil)
if err!= nil {
return nil, err
}
// Implement request with timeout
client := &http.Client{
Timeout: 5 * time.Second,
}
resp, err := client.Do(req)
if err!= nil {
return nil, err
}
defer resp.Body.Close()
// Process response
var user User
json.NewDecoder(resp.Body).Decode(&user)
return &user, nil
}
Flux du contexte (Context) dans les systèmes distribués
graph TD
A[Requête client] --> B[Passerelle API]
B --> C[Service 1]
B --> D[Service 2]
C --> E[Requête à la base de données]
D --> F[Appel à une API externe]
E --> G[Agrégation des réponses]
F --> G
Opérations sur la base de données
Requêtes à la base de données annulables
func fetchLargeDataset(ctx context.Context, db *sql.DB) ([]Record, error) {
// Create cancellable query
query := "SELECT * FROM large_table"
rows, err := db.QueryContext(ctx, query)
if err!= nil {
return nil, err
}
defer rows.Close()
var records []Record
for rows.Next() {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
var record Record
if err := rows.Scan(&record); err!= nil {
return nil, err
}
records = append(records, record)
}
}
return records, nil
}
Gestion des opérations concurrentes
Appels d'API parallèles avec contexte (Context)
func fetchMultipleAPIs(ctx context.Context) ([]Result, error) {
// Create child contexts with individual timeouts
ctx1, cancel1 := context.WithTimeout(ctx, 3*time.Second)
ctx2, cancel2 := context.WithTimeout(ctx, 4*time.Second)
defer cancel1()
defer cancel2()
// Parallel API calls
var results []Result
var mu sync.Mutex
var wg sync.WaitGroup
apis := []string{
"https://api1.example.com",
"https://api2.example.com",
}
for _, apiURL := range apis {
wg.Add(1)
go func(url string, ctx context.Context) {
defer wg.Done()
result, err := fetchAPI(ctx, url)
if err == nil {
mu.Lock()
results = append(results, result)
mu.Unlock()
}
}(apiURL, ctx)
}
wg.Wait()
return results, nil
}
Modèles d'utilisation du contexte (Context)
Modèle |
Description |
Cas d'utilisation |
Contrôle du délai (Timeout Control) |
Limiter la durée d'une opération |
Requêtes réseau, calculs longs |
Annulation (Cancellation) |
Arrêter les processus en cours |
Annulation initiée par l'utilisateur |
Propagation de valeurs (Value Propagation) |
Partager les métadonnées de la requête |
Journalisation, suivi, authentification |
Stratégies de gestion des erreurs
func robustOperation(ctx context.Context) error {
// Implement sophisticated error handling
select {
case <-ctx.Done():
return fmt.Errorf("operation canceled: %v", ctx.Err())
default:
// Perform primary logic
}
return nil
}
- Minimisez la charge du contexte (context)
- Utilisez le contexte de manière judicieuse
- Évitez les imbrications profondes de contextes
- Libérez les ressources rapidement
Techniques avancées
- Combinez plusieurs contextes
- Implémentez des types de contexte personnalisés
- Utilisez le contexte pour un arrêt gracieux
Conclusion
Maîtriser l'utilisation du contexte (context) est essentiel pour construire des applications évolutives et réactives. LabEx propose des ressources complètes pour approfondir votre compréhension du contexte en Golang.