type Balancer құрылымы { // TODO backends []*BackendImpl index int mu sync.Mutex N int K time.Duration } var _ Backend = &Balancer{} func (b *Balancer) Invoke(ctx context.Context, req Request) (Response, error) { if len(b.backends) == 0 { return nil, fmt.Errorf("Backends саны слайсте 0") } b.mu.Lock() index := b.index for b.backends[index].banned { b.index = (b.index + 1) % len(b.backends) index = b.index } b.index = (b.index + 1) % len(b.backends) b.mu.Unlock() backend := b.backends[index] resp, err := backend.Backend.Invoke(ctx, req) if err != nil && backend.countErrors < b.N { backend.mu.Lock() backend.countErrors += 1 if backend.countErrors == b.N { backend.banned = true go func() { time.Sleep(b.K) backend.mu.Lock() defer backend.mu.Unlock() backend.banned = false backend.countErrors = 0 }() } backend.mu.Unlock() } return resp, err } // addrs барлық балансирленетін экземплярлардың мекенжайларын қамтиды func NewBalancer(addrs []string) *Balancer { // TODO backends := make([]*BackendImplF, 0, len(addrs)) for _, addr := range addrs { implF := BackendImplF{ Backend: NewBackend(addr), } backends = append(backends, &implF) } return &Balancer{ backends: backends, } }
sobes.tech AI
AI-дан жауап
Көрсетілген кодта бірнеше мәселе бар:
NewBalancerфункциясындаbackendsслайсіlen(addrs)ұзындықта жасалады, бірақ циклда элементтердіappendарқылы қосу орын алады, бұл слайстің басындаlen(addrs)нөлдік элементтері болуына және кейін жаңа элементтердің қосылуына әкеледі. Нәтижесінде, слайстің ұзындығы қажеттен артық болады, ал алғашқы элементтерnilболады.
Дұрыс тәсіл — слайсты нөлдік ұзындықпен, бірақ қажетті сыйымдылықпен инициализациялау:
backends := make([]*BackendImplF, 0, len(addrs))
- Циклда индекс қолдану немесе дұрыс элементтерді қосу керек:
for _, addr := range addrs {
implF := BackendImplF{
Backend: NewBackend(addr),
}
backends = append(backends, &implF)
}
-
Balancerқұрылымындаbackendsөрісі[]*BackendImplретінде жарияланған, ал функциядаBackendImplFтипіндегі объектілер жасалады. Типтердің сәйкес келуін немесеBackendImplFинтерфейсті жүзеге асыратынын тексеру керек. -
Invokeәдісінде мьютекс блоктау бекітілген, бұл дұрыс, себебі ол индексті өзгерту және backend таңдау үшін пайдаланылады. -
Backend-тің қателер саны шектен асқанда банға қою және оны уақытша жою логикасы дұрыс жүзеге асырылған.
Қорытынды: NewBalancer функциясында слайсты дұрыс инициализациялап, nil элементтер мен дұрыс емес ұзындықтан аулақ болыңыз, сонымен қатар типтердің сәйкестігін тексеріңіз.