Skip to content
Catégories:

Fanplace Qu’est-ce que Fanplace in Go : guide complet

Post date:

Qu’est-ce que Fanplace ?

Fanplace est une bibliothèque open source développée en Go (Golang) qui simplifie la mise en œuvre des modèles de compétition entrée/sortie.
Ces modèles, très appréciés dans les applications distribuées ou les services à haute disponibilité, sont constitués de distribuer (distribuer) le même lot de tâches à plusieurs goroutines puis à groupe (fan-in) donne un seul flux.
Fanplace encapsule les détails de l’implémentation: création de travailleurs, gestion du contexte, collecte des erreurs, filtrage et agrégation des résultats, tout en restant léger et efficace.

Faits saillants immédiats

  • Lisibilité : quelques lignes de code pour orchestrer des dizaines ou des centaines de Workers.
  • Sécurité : protection contre les fuites courantes grâce à l’utilisation systématique de context.Context.
  • Résilience : optionnalité de tentatives intégrées, d’interruption, d’annulation et de délais d’attente.
  • Extensibilité : personnalisable via des interfaces et des rappels pour s’adapter aux besoins spécifiques.

Pourquoi choisir Fanplace ?

Les développeurs Go sont souvent confrontés à ces défis:

Problème Fanplace propose-t-il une solution ?
Supplément standard démarrer/arrêter les travailleurs Oui, la bibliothèque gère l’intégralité du cycle de vie.
Gestion de l’état de la race entre les goroutines Oui, l’agrégation des résultats est thread-safe.
Coordination d’annulation (timeout, annuler) Oui, grâce à context.
Agrégation simultanée des résultats Oui, via un seul canal d’entrée et un canal de sortie contrôlé.
Réactivité aux erreurs (propagation, réessayez) Oui, avec la politique de file d’attente des tâches de resoumission configurable.

En bref, Fanplace réduit la surface d’erreur et accélère le temps de développement de services hautement compétitifs.

Installation et configuration initiale

go get github.com/myorg/fanplace/v2
package main

import (
    "context"
    "fmt"
    "github.com/myorg/fanplace/v2"
)

func main() {
    ctx := context.Background()
    // Crée un pool de 10 workers
    p := fanplace.NewPool(10)

    // Fonction métier
    worker := func(ctx context.Context, task interface{}) (interface{}, error) {
        // Simuler un traitement
        number := task.(int)
        return number * number, nil
    }

    // Exécuter 100 tâches
    results, err := p.Execute(ctx, worker, fanplace.TasksFromSlice([]int{1, 2, 3, 4, 5}))
    if err != nil {
        panic(err)
    }
    fmt.Println(results) // [1, 4, 9, 16, 25]
}

Principaux points de configuration

  • fanplace.NewPool(n) : crée un ensemble de n ouvriers.
  • worker : fonction qui reçoit un context.Context et un task et renvoie un résultat ou une erreur.
  • fanplace.TasksFromSlice([]int{…}) : convertit une tranche en source de tâches interne.
  • p.Execute : Déclenche le processus et renvoie une tranche des résultats ou une erreur globale.

Technique architecturale

1. Le pool de travailleurs

Chaque travailleur gère sa propre goroutine et lit les tâches depuis un canal interne.
ET sync.WaitGroup s’assure que la fermeture est respectée lorsque tous les travailleurs ont terminé.

2. Canal d’entrée/sortie

  • tasks : canal non tamponné (configurable en option).
  • results : canal tamponné de la même taille que tasks pour éviter de bloquer les travailleurs.

3. Gestion du contexte

Chaque travailleur reçoit le même context.Context transmis à Execute. Toute annulation (timeout, annulation) est propagée et arrêtée correctement.

4. Agrégation d’erreurs

La fonction Execute renvoie un erreur composée (taper fanplace.MultiError) regroupant tous les échecs.
Les erreurs peuvent être filtrées avec un middleware ErrorHandler.

5. Réessayez et reculez

Fanplace fournit un middleware Retry qui, lorsqu’une tâche échoue, la réinjecte dans le pool après un délai de récupération exponentiel.

RetryOptions{
    MaxRetries: 3,
    BaseDelay:  100 * time.Millisecond,
}

Exemple complet – traitement parallèle

Disons que nous avons un service de géocodage qui doit appeler une API externe pour 200 adresses.

type GeoResult struct {
    Address string
    Lat, Lon float64
}

func geoWorker(ctx context.Context, task interface{}) (interface{}, error) {
    addr := task.(string)
    // Appel réseau simulé
    res, err := fakeGeocodeAPI(addr)
    if err != nil {
        return nil, err
    }
    return GeoResult{Address: addr, Lat: res.Lat, Lon: res.Lon}, nil
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    pool := fanplace.NewPool(20) // 20 workers

    addresses := []string{"Paris", "Berlin", ...}

    results, err := pool.Execute(ctx, geoWorker, fanplace.TasksFromSlice(addresses))
    if err != nil {
        fmt.Println("Erreur durant le géocodage :", err)
        return
    }

    for _, r := range results {
        res := r.(GeoResult)
        fmt.Printf("%s → [%f, %f]n", res.Address, res.Lat, res.Lon)
    }
}

Points d’attention

  • Contexte : Limite la durée totale du géocodage à 10 s.
  • Piscine : 20 travailleurs réduisent le temps d’attente autorisé par l’API tierce.
  • Agrégation : Les résultats sont récupérés et affichés de manière ordonnée.

Gestion des erreurs et délais d’attente

Fanplace expose deux mécanismes principaux:

  1. Erreur composée :

    if err != nil {
       if merr, ok := err.(fanplace.MultiError); ok {
           for _, e := range merr.Errors {
               fmt.Println("Task failed:", e)
           }
       }
    }
  2. Résiliation gracieuse :
    Si le contexte expire pendant l’exécution, les travailleurs termineront leur tâche en cours et le pool sera fermé sans laisser de goroutine dans une impasse.

Intégration avec d’autres outils Go

Outil Intégration possible
Prométhée Instrumentation personnalisée sur le nombre de tâches, la latence moyenne, les erreurs.
Gin Utilisez Fanplace pour exécuter des tâches de longue durée en arrière-plan après la réponse HTTP.
Transaction de base de données Exécutez la récupération des données en parallèle, puis validez-les dans une transaction.
Fonctions AWS Lambda/GCP Exécutez Fanplace dans un rôle sans serveur pour transformer un grand volume de données sans dépasser les limites de temps.

Exemple d’instrumentation:

import "github.com/prometheus/client_golang/prometheus"

var (
    tasksProcessed = prometheus.NewCounter(prometheus.CounterOpts{
        Name: "fanplace_tasks_processed",
        Help: "Nombre de tâches traitées.",
    })
)

Bonnes pratiques d’utilisation de Fanplace

Meilleures pratiques De sorte que
Limiter les noms des travailleurs Empêche la saturation du système et les pannes de batterie.
Utiliser un contexte chronométré Garantit qu’une tâche bloquée n’en retarde pas les autres.
Gérer correctement les erreurs Empêche la propagation des erreurs silencieuses.
Profil de la piscine Vérifiez que la latence ne dépasse pas les attentes.
Documenter les tâches Facilite la maintenance et augmente l’expertise.

Avantages par rapport à une implémentation brute

Technique Passez au brut (canaux/goroutines) Fanplace
Standard Long et sujet aux erreurs Écrire automatiquement
Gestion du contexte Manuel et répétitif Intégré
Collecte d’erreurs Tu dois te gérer MultiErreur
Nouvelles tentatives Mettre en œuvre pour chaque tâche Middleware prêt à l’emploi
Testabilité Complexe à moquer Facile grâce aux interfaces

Conclusion – Pourquoi Fanplace est votre meilleur allié

Fanplace s’avère être l’outil idéal pour les développeurs Go qui souhaitent:

  • Lancez rapidement des traitements parallèles complexes.
  • Gardez le code clair et facile à maintenir.
  • Gérez les erreurs et les annulations avec élégance.
  • Intégrez facilement des stratégies de retrait et de nouvelle tentative.

Avec Fanplace, vous libérez votre équipe des tâches répétitives et permettez à votre application de rester efficace, robuste et évolutive. Essayez-le maintenant pour transformer votre approche simultanée de Go.