В Go есть несколько способов ограничить отправку запросов из горутин для предотвращения перегрузки системы или превышения ограничений сторонних сервисов. Рассмотрим некоторые из них.
1. Использование буферизованных каналов: Вы можете создать канал с ограниченной емкостью и использовать его для передачи запросов. Если канал заполнен, отправка новых запросов будет блокироваться до тех пор, пока не освободится место в канале. Например:
requests := make(chan Request, 10) responses := make(chan Response) // создаем горутину-обработчик go func() { for req := range requests { // выполняем запрос и отправляем результат в канал responses resp := makeRequest(req) responses <- resp } }() // отправляем запросы в канал requests for _, req := range allRequests { requests <- req } // получаем результаты из канала responses for i := 0; i < len(allRequests); i++ { resp := <-responses // обрабатываем результат }
2. Использование пула горутин: Вы можете создать ограниченное количество горутин в пуле и использовать его для обработки запросов. Когда все горутины заняты, новые запросы будут вставлены в очередь и ожидать своей очереди. Например:
const maxWorkers = 10 type WorkerPool struct { workers chan struct{} } func NewWorkerPool() *WorkerPool { return &WorkerPool{ workers: make(chan struct{}, maxWorkers), } } func (p *WorkerPool) Submit(f func()) { p.workers <- struct{}{} go func() { f() <-p.workers }() } pool := NewWorkerPool() for _, req := range allRequests { pool.Submit(func() { // обрабатываем запрос resp := makeRequest(req) // обрабатываем результат }) }
3. Использование семафоров: Вы можете использовать семафоры для управления количеством одновременно выполняемых горутин. Семафор — это счетчик, который контролирует количество разрешений для выполнения. Например:
const maxConcurrency = 5 var sem = make(chan struct{}, maxConcurrency) for _, req := range allRequests { sem <- struct{}{} go func(r Request) { // обрабатываем запрос resp := makeRequest(r) // обрабатываем результат <-sem }(req) }
Это только несколько примеров, как можно ограничить отправку запросов из горутин. В зависимости от конкретной ситуации и требований, вы можете использовать один из этих подходов или их комбинацию для эффективного управления параллельной обработкой запросов в вашей программе на Go.