From 7a8c6a9b54f210274ab22f50c7b1d000e36c8685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Gyllensw=C3=A4rd?= Date: Mon, 18 Nov 2019 16:58:15 +0100 Subject: [PATCH] Reporting: Handle timeouts in rendering (#20415) * Added timeout in grpc call to plugins for rendering --- pkg/api/render.go | 3 ++- pkg/services/rendering/interface.go | 4 +++- pkg/services/rendering/plugin_mode.go | 3 +++ pkg/services/rendering/rendering.go | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/api/render.go b/pkg/api/render.go index 3fcb99d8121..a4e2c6ed29c 100644 --- a/pkg/api/render.go +++ b/pkg/api/render.go @@ -40,6 +40,7 @@ func (hs *HTTPServer) RenderToPng(c *m.ReqContext) { return } + maxConcurrentLimitForApiCalls := 30 result, err := hs.RenderService.Render(c.Req.Context(), rendering.Opts{ Width: width, Height: height, @@ -50,7 +51,7 @@ func (hs *HTTPServer) RenderToPng(c *m.ReqContext) { Path: c.Params("*") + queryParams, Timezone: queryReader.Get("tz", ""), Encoding: queryReader.Get("encoding", ""), - ConcurrentLimit: 30, + ConcurrentLimit: maxConcurrentLimitForApiCalls, }) if err != nil && err == rendering.ErrTimeout { diff --git a/pkg/services/rendering/interface.go b/pkg/services/rendering/interface.go index 39cb1ada0f5..c959960aff8 100644 --- a/pkg/services/rendering/interface.go +++ b/pkg/services/rendering/interface.go @@ -26,11 +26,13 @@ type Opts struct { } type RenderResult struct { - FilePath string + FilePath string + KeepFileAfterRender bool } type renderFunc func(ctx context.Context, options Opts) (*RenderResult, error) type Service interface { Render(ctx context.Context, opts Opts) (*RenderResult, error) + RenderErrorImage(error error) (*RenderResult, error) } diff --git a/pkg/services/rendering/plugin_mode.go b/pkg/services/rendering/plugin_mode.go index 32a1a38ac3e..44c7a2f154b 100644 --- a/pkg/services/rendering/plugin_mode.go +++ b/pkg/services/rendering/plugin_mode.go @@ -63,6 +63,9 @@ func (rs *RenderingService) renderViaPlugin(ctx context.Context, opts Opts) (*Re return nil, err } + ctx, cancel := context.WithTimeout(ctx, opts.Timeout) + defer cancel() + rsp, err := rs.grpcPlugin.Render(ctx, &pluginModel.RenderRequest{ Url: rs.getURL(opts.Path), Width: int32(opts.Width), diff --git a/pkg/services/rendering/rendering.go b/pkg/services/rendering/rendering.go index 28abad3eccb..e3cce5d30e5 100644 --- a/pkg/services/rendering/rendering.go +++ b/pkg/services/rendering/rendering.go @@ -3,12 +3,11 @@ package rendering import ( "context" "fmt" + plugin "github.com/hashicorp/go-plugin" "net/url" "os" "path/filepath" - plugin "github.com/hashicorp/go-plugin" - pluginModel "github.com/grafana/grafana-plugin-model/go/renderer" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/middleware" @@ -93,10 +92,20 @@ func (rs *RenderingService) Run(ctx context.Context) error { return err } +func (rs *RenderingService) RenderErrorImage(err error) (*RenderResult, error) { + imgUrl := "public/img/rendering_error.png" + + return &RenderResult{ + FilePath: filepath.Join(setting.HomePath, imgUrl), + KeepFileAfterRender: true, + }, nil +} + func (rs *RenderingService) Render(ctx context.Context, opts Opts) (*RenderResult, error) { if rs.inProgressCount > opts.ConcurrentLimit { return &RenderResult{ - FilePath: filepath.Join(setting.HomePath, "public/img/rendering_limit.png"), + FilePath: filepath.Join(setting.HomePath, "public/img/rendering_limit.png"), + KeepFileAfterRender: true, }, nil }