Search code examples
gochannelgoroutine

Buffered channel size limit


Hi there I have written this code to simulate sending emails asynchronously but if I send 500 concurrent requests to this server the first 100 requests will be able to enqueue their emails into the channel without blocking, but the subsequent requests will block until there is space available in the channel. This could lead to bottleneck into my system

package main

import (
    "fmt"
    "net/http"
    "time"
)
var count = 0;

var queue chan int

func sendEmail(){
    for email := range queue {
        time.Sleep(2 * time.Second)
        fmt.Println(email)
    }
}

func main() {
    go sendEmail()

    queue = make(chan int, 100)
    defer close(queue)

    http.ListenAndServe(":5000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        count++
        queue <- count
        w.Write([]byte("email will be sent shortly"))
    }))
}

So what should be the highest buffer size I can set to the channel? But again if the number of concurrent requests is significantly larger than the buffer size, it may still lead to blocking. What would be optimal approach to handle this kind of scenario


Solution

  • To be clear, this is not specific to Go, this happens any time you have a queue. At a certain point you will run out of resources, be it memory or disk (if the queue is persisted).

    You need to decide what to do and how to give feedback to the sender, this is called back pressure. This is a big topic, see for example: