处理程序达到最大客户端限制时返回错误

Abh*_*nav 5 go mux

我编写了一个小的包装函数,该函数使用计数信号量概念来限制到特定处理程序的连接数(因为此处理程序很耗资源)。下面是实现相同功能的代码。

func LimitNumClients(f http.HandlerFunc, maxClients int) http.HandlerFunc {
    // Counting semaphore using a buffered channel
    sema := make(chan struct{}, maxClients)

    return func(w http.ResponseWriter, req *http.Request) {
        sema <- struct{}{}
        defer func() { <-sema }()
        f(w, req)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其包装在处理程序中,如下所示

Route{
        "Test",
        "GET",
        /test,
        LimitNumClients(testhandler, 5),
    },
Run Code Online (Sandbox Code Playgroud)

现在,当任何新连接达到客户端限制时,我想以501错误回复。如何实现相同。

icz*_*cza 6

您可以使用非阻塞发送操作。如果成功,则继续正常操作,如果继续发送sema将阻塞,然后发送错误并从限制器返回而无需调用处理程序:

return func(w http.ResponseWriter, req *http.Request) {
    select {
    case sema <- struct{}{}:
    default:
        http.Error(w, "rate limit reached", 501)
        return
    }

    defer func() { <-sema }()
    f(w, req)
}
Run Code Online (Sandbox Code Playgroud)

还要注意的是信号是“限速达”的错误,返回的状态码应该是HTTP 429 Too Many Requests,见RFC 6585

所以改为返回:

http.Error(w, "rate limit reached", http.StatusTooManyRequests)
Run Code Online (Sandbox Code Playgroud)