github.com/xmidt-org/webpa-common@v1.11.9/xhttp/busy.go (about)

     1  package xhttp
     2  
     3  import (
     4  	"net/http"
     5  
     6  	"github.com/go-kit/kit/log/level"
     7  	"github.com/xmidt-org/webpa-common/logging"
     8  	"github.com/xmidt-org/webpa-common/semaphore"
     9  )
    10  
    11  // Busy creates an Alice-style constructor that limits the number of HTTP transactions handled by decorated
    12  // handlers.  The decorated handler blocks waiting on a semaphore until the request's context is canceled.
    13  // If a transaction is not allowed to proceed, http.StatusServiceUnavailable.
    14  func Busy(maxTransactions int) func(http.Handler) http.Handler {
    15  	s := semaphore.New(maxTransactions)
    16  	return func(next http.Handler) http.Handler {
    17  		return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
    18  			ctx := request.Context()
    19  
    20  			if err := s.AcquireCtx(ctx); err != nil {
    21  				logging.GetLogger(ctx).Log(level.Key(), level.ErrorValue(), logging.MessageKey(), "server busy", logging.ErrorKey(), request.Context().Err())
    22  				response.WriteHeader(http.StatusServiceUnavailable)
    23  				return
    24  			}
    25  
    26  			defer s.Release()
    27  			next.ServeHTTP(response, request)
    28  		})
    29  	}
    30  }