Sobes.tech
Middle

Go'da gorutinlarda yuzaga keladigan xatoliklarni qanday boshqarish usuli qo'llaniladi?

sobes.tech AI

AIdan javob

Go'da, gorutinlarda xatoliklarni boshqarish uchun odatda quyidagi yondashuvlar qo'llaniladi:

  • Xatoliklarni kanallar orqali uzatish: Xatolik qiymatlarini asosiy yoki boshqa gorutinga uzatish uchun kanal yaratiladi, ularni qayta ishlash uchun.

    // Kanal orqali xatolikni uzatish misoli
    func worker(id int, errors chan<- error) {
      // ... ishni bajarish
      if somethingWentWrong {
        errors <- fmt.Errorf("gorutinada xato %d", id)
        return
      }
      // ... muvaffaqiyatli yakunlash
    }
    
    func main() {
      errorCh := make(chan error, nWorkers) // Bufferli kanal
      for i := 0; i < nWorkers; i++ {
        go worker(i, errorCh)
      }
    
      for i := 0; i < nWorkers; i++ {
        err := <-errorCh
        if err != nil {
          log.Printf("topilgan xato: %v", err)
          // Xatoni qayta ishlash
        }
      }
    }
    
  • sync.WaitGroup va xatoliklar kanali bilan ishlash: sync.WaitGroup barcha gorutinalarning yakunlanishini kutishga yordam beradi, va kanal xatoliklarni yig'ish uchun ishlatiladi.

    // WaitGroup va xatoliklar kanali bilan misol
    func workerWithWG(id int, wg *sync.WaitGroup, errors chan<- error) {
      defer wg.Done()
      // ... ishni bajarish
      if somethingWentWrong {
        errors <- fmt.Errorf("gorutinada xato %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) // WaitGroupdan so'ng kanalni yopish muhim
    
      for err := range errorCh {
        log.Printf("topilgan xato: %v", err)
        // Xatoni qayta ishlash
      }
    }
    
  • Gorutinda bajariladigan funksiyadan qiymat va xatoni qaytarish: Agar goroutine ma'lum bir vazifani bajarayotgan bo'lsa va natija yoki xatoni qaytarishi mumkin bo'lsa, uni bu qiymatlarni qaytaradigan funktsiya ichiga o'rash mumkin.

    // Qiymat va xatoni qaytaradigan misol
    type result struct {
      value int
      err error
    }
    
    func doSomething(id int) (int, error) {
      // ... ishni bajarish
      if somethingWentWrong {
        return 0, fmt.Errorf("gorutina %d da xato", 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("topilgan xato: %v", res.err)
          // Xatoni qayta ishlash
        } else {
          log.Printf("natija: %d", res.value)
        }
      }
    }
    
  • Kontekst (context.Context) yordamida bekor qilish va xatoliklarni boshqarish: Kontekst gorutinalarni bekor qilish signalini berish yoki xatoliklarni pastga uzatish uchun ishlatilishi mumkin.

    // Kontekst bilan misol
    func workerWithContext(ctx context.Context, id int, errors chan<- error) {
      select {
      case <-ctx.Done():
        errors <- fmt.Errorf("goroutine %d bekor qilindi: %v", id, ctx.Err())
        return
      default:
        // ... ishni bajarish
        if somethingWentWrong {
          errors <- fmt.Errorf("gorutina %d da xato", 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)
      }
    
      // Bir ozdan so'ng, cancel() chaqirilishi mumkin
      // cancel()
    
      // Xatoliklarni yig'ish
      go func() {
        for err := range errorCh {
          log.Printf("topilgan xato: %v", err)
        }
      }()
    
      // Yakunlash yoki boshqa logika kutish
      // ...
    }
    

Ma'lum bir yondashuvni tanlash, xatoliklarni boshqarish talablari va ilova arxitekturasiga bog'liq.