Sobes.tech
Back to questions
Senior
5

func New(workers, queue, int) Scheduler { s := &scheduler { queue := make(chan Task, queue) for i := 0; i < workers; i++ { wg.Add(1) go func() { defer wg.Done() for task := range s.queue { task.Do() } }() } } return s } func (s *scheduler) Close() { close(s.queue) s.wg.Wait() } type Task interface { Do() }

Companies where asked
Cloud.ru

Answer from AI

sobes.tech AI

В представленном коде есть несколько ошибок и неточностей, которые стоит исправить для корректной работы планировщика задач (Scheduler) с воркерами и очередью.

  1. В сигнатуре функции New(workers, queue, int) Scheduler неверно указан тип параметров — нужно явно указать типы для каждого параметра, например: New(workers int, queue int) Scheduler.

  2. В инициализации структуры scheduler используется синтаксис queue := make(chan Task, queue), что является объявлением новой переменной, а не инициализацией поля структуры. Правильно будет использовать queue: make(chan Task, queue),.

  3. Отсутствует объявление wg (WaitGroup) в структуре scheduler и его инициализация.

  4. В горутине, которая запускается для каждого воркера, используется s.queue, но s еще не полностью инициализирован, что может привести к ошибкам.

  5. Отсутствует определение типа scheduler и интерфейса Scheduler.

Пример исправленного и упрощённого варианта:

package main

import (
    "sync"
)

type Task interface {
    Do()
}

type Scheduler interface {
    Schedule(task Task)
    Close()
}

type scheduler struct {
    queue chan Task
    wg    sync.WaitGroup
}

func New(workers int, queueSize int) Scheduler {
    s := &scheduler{
        queue: make(chan Task, queueSize),
    }

    s.wg.Add(workers)
    for i := 0; i < workers; i++ {
        go func() {
            defer s.wg.Done()
            for task := range s.queue {
                task.Do()
            }
        }()
    }

    return s
}

func (s *scheduler) Schedule(task Task) {
    s.queue <- task
}

func (s *scheduler) Close() {
    close(s.queue)
    s.wg.Wait()
}

В этом примере:

  • New создаёт планировщик с заданным числом воркеров и размером очереди.
  • Каждый воркер читает задачи из канала queue и выполняет метод Do().
  • Метод Schedule добавляет задачи в очередь.
  • Метод Close закрывает очередь и ждёт завершения всех воркеров.

Такой подход позволяет эффективно распараллелить выполнение задач с контролем завершения всех горутин.