Reduce memory utilization in downstream projects creating multiple Alertmanager instances (#3114)
* Reduce memory utilization in downstream projects creating multiple Alertmanager instances Signed-off-by: Marco Pracucci <marco@pracucci.com>
This commit is contained in:
parent
28c3df0173
commit
33bba95099
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
@ -101,7 +102,7 @@ func NewAPI(
|
|||
}
|
||||
|
||||
// Load embedded swagger file.
|
||||
swaggerSpec, err := getSwaggerSpec()
|
||||
swaggerSpec, swaggerSpecAnalysis, err := getSwaggerSpec()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -113,7 +114,9 @@ func NewAPI(
|
|||
// the API itself via RoutesHandler. See:
|
||||
// https://github.com/go-swagger/go-swagger/issues/1779
|
||||
openAPI.Middleware = func(b middleware.Builder) http.Handler {
|
||||
return middleware.Spec("", swaggerSpec.Raw(), openAPI.Context().RoutesHandler(b))
|
||||
// Manually create the context so that we can use the singleton swaggerSpecAnalysis.
|
||||
swaggerContext := middleware.NewRoutableContextWithAnalyzedSpec(swaggerSpec, swaggerSpecAnalysis, openAPI, nil)
|
||||
return middleware.Spec("", swaggerSpec.Raw(), swaggerContext.RoutesHandler(b))
|
||||
}
|
||||
|
||||
openAPI.AlertGetAlertsHandler = alert_ops.GetAlertsHandlerFunc(api.getAlertsHandler)
|
||||
|
@ -674,29 +677,31 @@ func parseFilter(filter []string) ([]*labels.Matcher, error) {
|
|||
}
|
||||
|
||||
var (
|
||||
swaggerSpecCacheMx sync.Mutex
|
||||
swaggerSpecCache *loads.Document
|
||||
swaggerSpecCacheMx sync.Mutex
|
||||
swaggerSpecCache *loads.Document
|
||||
swaggerSpecAnalysisCache *analysis.Spec
|
||||
)
|
||||
|
||||
// getSwaggerSpec loads and caches the swagger spec. If a cached version already exists,
|
||||
// it returns the cached one. The reason why we cache it is because some downstream projects
|
||||
// (e.g. Grafana Mimir) creates many Alertmanager instances in the same process, so they would
|
||||
// incur in a significant memory penalty if we would reload the swagger spec each time.
|
||||
func getSwaggerSpec() (*loads.Document, error) {
|
||||
func getSwaggerSpec() (*loads.Document, *analysis.Spec, error) {
|
||||
swaggerSpecCacheMx.Lock()
|
||||
defer swaggerSpecCacheMx.Unlock()
|
||||
|
||||
// Check if a cached version exists.
|
||||
if swaggerSpecCache != nil {
|
||||
return swaggerSpecCache, nil
|
||||
return swaggerSpecCache, swaggerSpecAnalysisCache, nil
|
||||
}
|
||||
|
||||
// Load embedded swagger file.
|
||||
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load embedded swagger file: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to load embedded swagger file: %w", err)
|
||||
}
|
||||
|
||||
swaggerSpecCache = swaggerSpec
|
||||
return swaggerSpec, nil
|
||||
swaggerSpecAnalysisCache = analysis.New(swaggerSpec.Spec())
|
||||
return swaggerSpec, swaggerSpecAnalysisCache, nil
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -9,9 +9,10 @@ require (
|
|||
github.com/cenkalti/backoff/v4 v4.1.3
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-openapi/analysis v0.21.4
|
||||
github.com/go-openapi/errors v0.20.3
|
||||
github.com/go-openapi/loads v0.21.2
|
||||
github.com/go-openapi/runtime v0.24.1
|
||||
github.com/go-openapi/runtime v0.24.3-0.20221021160911-4425b20330b2
|
||||
github.com/go-openapi/spec v0.20.7
|
||||
github.com/go-openapi/strfmt v0.21.3
|
||||
github.com/go-openapi/swag v0.22.3
|
||||
|
@ -54,7 +55,6 @@ require (
|
|||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -114,8 +114,8 @@ github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXym
|
|||
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
|
||||
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
|
||||
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
|
||||
github.com/go-openapi/runtime v0.24.1 h1:Sml5cgQKGYQHF+M7yYSHaH1eOjvTykrddTE/KtQVjqo=
|
||||
github.com/go-openapi/runtime v0.24.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk=
|
||||
github.com/go-openapi/runtime v0.24.3-0.20221021160911-4425b20330b2 h1:Vr08+BrsrnvcgikSlS273dkijppZ/M+fL/TMfc/LEJM=
|
||||
github.com/go-openapi/runtime v0.24.3-0.20221021160911-4425b20330b2/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI=
|
||||
|
|
Loading…
Reference in New Issue