Browse Source

rendering: Added concurrent rendering limits

Torkel Ödegaard 7 years ago
parent
commit
4dab595ed7

+ 2 - 0
conf/defaults.ini

@@ -550,3 +550,5 @@ container_name =
 # Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
 server_url =
 callback_url =
+concurrent_limit = 10
+concurrent_limit_alerting = 5

+ 2 - 0
conf/sample.ini

@@ -471,3 +471,5 @@ log_queries =
 # Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
 ;server_url =
 ;callback_url =
+;concurrent_limit = 10
+;concurrent_limit_alerting = 5

+ 1 - 0
pkg/services/alerting/notifier.go

@@ -113,6 +113,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) {
 		Timeout: alertTimeout / 2,
 		OrgId:   context.Rule.OrgId,
 		OrgRole: m.ROLE_ADMIN,
+		IsAlert: true,
 	}
 
 	ref, err := context.GetDashboardUID()

+ 1 - 1
pkg/services/alerting/result_handler.go

@@ -100,7 +100,7 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error {
 			}
 		}
 	}
-	handler.notifier.SendIfNeeded(evalContext)
 
+	handler.notifier.SendIfNeeded(evalContext)
 	return nil
 }

+ 1 - 0
pkg/services/rendering/interface.go

@@ -22,6 +22,7 @@ type Opts struct {
 	Path     string
 	Encoding string
 	Timezone string
+	IsAlert  bool
 }
 
 type RenderResult struct {

+ 27 - 6
pkg/services/rendering/rendering.go

@@ -24,12 +24,13 @@ func init() {
 }
 
 type RenderingService struct {
-	log          log.Logger
-	pluginClient *plugin.Client
-	grpcPlugin   pluginModel.RendererPlugin
-	pluginInfo   *plugins.RendererPlugin
-	renderAction renderFunc
-	domain       string
+	log             log.Logger
+	pluginClient    *plugin.Client
+	grpcPlugin      pluginModel.RendererPlugin
+	pluginInfo      *plugins.RendererPlugin
+	renderAction    renderFunc
+	domain          string
+	inProgressCount int
 
 	Cfg *setting.Cfg `inject:""`
 }
@@ -89,7 +90,27 @@ func (rs *RenderingService) Run(ctx context.Context) error {
 	return err
 }
 
+func (rs *RenderingService) getLimit(isAlerting bool) int {
+	if isAlerting {
+		return rs.Cfg.RendererLimitAlerting
+	} else {
+		return rs.Cfg.RendererLimit
+	}
+}
+
 func (rs *RenderingService) Render(ctx context.Context, opts Opts) (*RenderResult, error) {
+	if rs.inProgressCount > rs.getLimit(opts.IsAlert) {
+		return &RenderResult{
+			FilePath: filepath.Join(setting.HomePath, "public/img/rendering_limit.png"),
+		}, nil
+	}
+
+	defer func() {
+		rs.inProgressCount -= 1
+	}()
+
+	rs.inProgressCount += 1
+
 	if rs.renderAction != nil {
 		return rs.renderAction(ctx, opts)
 	} else {

+ 10 - 4
pkg/setting/setting.go

@@ -196,10 +196,13 @@ type Cfg struct {
 	Smtp SmtpSettings
 
 	// Rendering
-	ImagesDir                        string
-	PhantomDir                       string
-	RendererUrl                      string
-	RendererCallbackUrl              string
+	ImagesDir             string
+	PhantomDir            string
+	RendererUrl           string
+	RendererCallbackUrl   string
+	RendererLimit         int
+	RendererLimitAlerting int
+
 	DisableBruteForceLoginProtection bool
 
 	TempDataLifetime time.Duration
@@ -645,6 +648,9 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
 
 	// Rendering
 	renderSec := iniFile.Section("rendering")
+	cfg.RendererLimit = renderSec.Key("concurrent_limit").MustInt(10)
+	cfg.RendererLimitAlerting = renderSec.Key("concurrent_limit").MustInt(5)
+
 	cfg.RendererUrl = renderSec.Key("server_url").String()
 	cfg.RendererCallbackUrl = renderSec.Key("callback_url").String()
 	if cfg.RendererCallbackUrl == "" {

BIN
public/img/rendering_error.png


BIN
public/img/rendering_limit.png


BIN
public/img/rendering_plugin_not_installed.png


BIN
public/img/rendering_timeout.png