gddo-server: add a semaphore to limit concurrent graph requests

There should be an upper bound for the number of "dot" processes
that can be started concurrently in order to serve incoming HTTP
requests for the ?import-graph pages, to help avoid resource
exhaustion and server overload.

This change implements a limit of 10 such processes at once.

Change-Id: I65d01996461ae212bb84cfd8edfbe6fcec43c329
Reviewed-on: https://go-review.googlesource.com/c/gddo/+/234637
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Dmitri Shuralyov 2020-05-19 16:18:03 -04:00
Родитель 3c2cc9a632
Коммит a4ebd2f7e5
1 изменённых файлов: 15 добавлений и 2 удалений

Просмотреть файл

@ -328,6 +328,15 @@ func (s *server) servePackage(resp http.ResponseWriter, req *http.Request) error
if pdoc.Name == "" {
return &httpError{status: http.StatusNotFound}
}
// Throttle ?import-graph requests.
select {
case s.importGraphSem <- struct{}{}:
default:
return &httpError{status: http.StatusTooManyRequests}
}
defer func() { <-s.importGraphSem }()
hide := database.ShowAllDeps
switch req.Form.Get("hide") {
case "1":
@ -866,12 +875,16 @@ type server struct {
statusSVG http.Handler
root rootHandler
// A semaphore to limit concurrent ?import-graph requests.
importGraphSem chan struct{}
}
func newServer(ctx context.Context, v *viper.Viper) (*server, error) {
s := &server{
v: v,
httpClient: newHTTPClient(v),
v: v,
httpClient: newHTTPClient(v),
importGraphSem: make(chan struct{}, 10),
}
var err error