mirror of
https://github.com/grafana/grafana.git
synced 2024-11-30 12:44:10 -06:00
PublicDashboards: Make mixed datasource calls concurrently (#56421)
PublicDashboards: Make mixed datasource calls concurrently
This commit is contained in:
parent
d9cc292066
commit
69c49f6ba2
@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func ProvideService(
|
||||
@ -90,18 +91,31 @@ func (s *Service) QueryDataMultipleSources(ctx context.Context, user *user.Signe
|
||||
} else {
|
||||
resp := backend.NewQueryDataResponse()
|
||||
|
||||
// create new reqDTO with only the queries for that datasource
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
results := make([]backend.Responses, len(byDataSource))
|
||||
|
||||
for _, queries := range byDataSource {
|
||||
subDTO := reqDTO.CloneWithQueries(queries)
|
||||
dataSourceQueries := queries
|
||||
g.Go(func() error {
|
||||
subDTO := reqDTO.CloneWithQueries(dataSourceQueries)
|
||||
|
||||
subResp, err := s.QueryData(ctx, user, skipCache, subDTO, handleExpressions)
|
||||
|
||||
if err != nil {
|
||||
if err == nil {
|
||||
results = append(results, subResp.Responses)
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for refId, queryResponse := range subResp.Responses {
|
||||
resp.Responses[refId] = queryResponse
|
||||
for _, result := range results {
|
||||
for refId, dataResponse := range result {
|
||||
resp.Responses[refId] = dataResponse
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,43 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("error is returned when one of the queries fails", func(t *testing.T) {
|
||||
tc := setup(t)
|
||||
|
||||
query1, _ := simplejson.NewJson([]byte(`
|
||||
{
|
||||
"datasource": {
|
||||
"type": "mysql",
|
||||
"uid": "ds1"
|
||||
}
|
||||
}
|
||||
`))
|
||||
query2, _ := simplejson.NewJson([]byte(`
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "ds2"
|
||||
},
|
||||
"queryType": "FAIL"
|
||||
}
|
||||
`))
|
||||
|
||||
queries := []*simplejson.Json{query1, query2}
|
||||
|
||||
reqDTO := dtos.MetricRequest{
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
HTTPRequest: nil,
|
||||
}
|
||||
|
||||
_, err := tc.queryService.QueryDataMultipleSources(context.Background(), nil, true, reqDTO, false)
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestQueryData(t *testing.T) {
|
||||
@ -255,7 +292,6 @@ func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasource
|
||||
|
||||
type fakePluginClient struct {
|
||||
plugins.Client
|
||||
|
||||
req *backend.QueryDataRequest
|
||||
}
|
||||
|
||||
@ -267,5 +303,9 @@ func (c *fakePluginClient) QueryData(ctx context.Context, req *backend.QueryData
|
||||
return nil, errors.New("cant query an expression datasource")
|
||||
}
|
||||
|
||||
if req.Queries[0].QueryType == "FAIL" {
|
||||
return nil, errors.New("plugin client failed")
|
||||
}
|
||||
|
||||
return &backend.QueryDataResponse{Responses: make(backend.Responses)}, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user