Sobes.tech
Middle

Aký prístup sa používa na spracovanie chýb, ktoré vznikajú v goroutines v Go?

sobes.tech AI

Odpoveď od AI

V Go sa zvyčajne používajú na spracovanie chýb v gorutinách nasledujúce prístupy:

  • Prenos chýb cez kanály: Vytvorí sa kanál na prenos hodnôt chýb do hlavného toku alebo do inej gorutiny, ktorá ich môže spracovať.

    // Príklad prenosu chyby cez kanál
    func worker(id int, errors chan<- error) {
      // ... vykonanie práce
      if somethingWentWrong {
        errors <- fmt.Errorf("chyba v gorutine %d", id)
        return
      }
      // ... úspešné dokončenie
    }
    
    func main() {
      errorCh := make(chan error, nWorkers) // Bufferovaný kanál
      for i := 0; i < nWorkers; i++ {
        go worker(i, errorCh)
      }
    
      for i := 0; i < nWorkers; i++ {
        err := <-errorCh
        if err != nil {
          log.Printf("zistená chyba: %v", err)
          // Spracovanie chyby
        }
      }
    }
    
  • Použitie sync.WaitGroup a kanála chýb: sync.WaitGroup pomáha počkať na dokončenie všetkých gorutín, zatiaľ čo kanál sa používa na zber chýb.

    // Príklad s WaitGroup a kanálom chýb
    func workerWithWG(id int, wg *sync.WaitGroup, errors chan<- error) {
      defer wg.Done()
      // ... vykonanie práce
      if somethingWentWrong {
        errors <- fmt.Errorf("chyba v gorutine %d", id)
      }
    }
    
    func main() {
      var wg sync.WaitGroup
      errorCh := make(chan error, nWorkers)
    
      for i := 0; i < nWorkers; i++ {
        wg.Add(1)
        go workerWithWG(i, &wg, errorCh)
      }
    
      wg.Wait()
      close(errorCh) // Je dôležité zatvoriť kanál po `WaitGroup`
    
      for err := range errorCh {
        log.Printf("zistená chyba: %v", err)
        // Spracovanie chyby
      }
    }
    
  • Vrátenie hodnoty a chyby z funkcie spúšťanej v gorutine: Ak gorutina vykonáva konkrétnu úlohu a môže vrátiť výsledok a/alebo chybu, môže byť zabalená do funkcie, ktorá tieto hodnoty vráti.

    // Príklad vrátenia hodnoty a chyby z funkcie
    type result struct {
      value int
      err error
    }
    
    func doSomething(id int) (int, error) {
      // ... vykonanie práce
      if somethingWentWrong {
        return 0, fmt.Errorf("chyba v gorutine %d", id)
      }
      return id * 10, nil
    }
    
    func main() {
      results := make(chan result, nWorkers)
    
      for i := 0; i < nWorkers; i++ {
        go func(idx int) {
          val, err := doSomething(idx)
          results <- result{val, err}
        }(i)
      }
    
      for i := 0; i < nWorkers; i++ {
        res := <-results
        if res.err != nil {
          log.Printf("zistená chyba: %v", res.err)
          // Spracovanie chyby
        } else {
          log.Printf("výsledok: %d", res.value)
        }
      }
    }
    
  • Použitie kontextu (context.Context) na zrušenie a spracovanie chýb: Kontext sa môže použiť na signalizáciu zrušenia gorutín alebo na prenos chyby nadol v hierarchii volaní.

    // Príklad s kontextom
    func workerWithContext(ctx context.Context, id int, errors chan<- error) {
      select {
      case <-ctx.Done():
        errors <- fmt.Errorf("gorutina %d zrušená: %v", id, ctx.Err())
        return
      default:
        // ... vykonanie práce
        if somethingWentWrong {
          errors <- fmt.Errorf("chyba v gorutine %d", id)
        }
      }
    }
    
    func main() {
      ctx, cancel := context.WithCancel(context.Background())
      errorCh := make(chan error, nWorkers)
    
      for i := 0; i < nWorkers; i++ {
        go workerWithContext(ctx, i, errorCh)
      }
    
      // V určitom momente možno zavolať cancel() na zrušenie
      // cancel()
    
      // Zber chýb
      go func() {
        for err := range errorCh {
          log.Printf("zistená chyba: %v", err)
        }
      }()
    
      // Čakanie na dokončenie alebo inú logiku
      // ...
    }
    

Výber konkrétneho prístupu závisí od požiadaviek na spracovanie chýb a architektúry aplikácie.