Query: Fix concurrency handling for mixed datasource queries (#70100)
* split queries and merge responses * increase concurrency again * update unit test to verify the headers are merged * fix lint issue * fix race condition in unit test * Fix function name and add a bit more documentation about how the func should be used * update function call after rename * check for duplicate header vals * make concurrent query limit configurable * Update conf/sample.ini Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com> --------- Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
This commit is contained in:
co-authored by
Sofia Papagiannaki
parent
d6c468c1c2
commit
ff6d6659fb
@@ -6,7 +6,10 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -21,6 +24,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/models/roletype"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
@@ -289,9 +293,23 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
}
|
||||
|
||||
_, err = tc.queryService.QueryData(context.Background(), tc.signedInUser, true, reqDTO)
|
||||
|
||||
req, err := http.NewRequest("POST", "http://localhost:3000", nil)
|
||||
require.NoError(t, err)
|
||||
reqCtx := &contextmodel.ReqContext{
|
||||
SkipQueryCache: false,
|
||||
Context: &web.Context{
|
||||
Resp: web.NewResponseWriter(http.MethodGet, httptest.NewRecorder()),
|
||||
Req: req,
|
||||
},
|
||||
}
|
||||
ctx := ctxkey.Set(context.Background(), reqCtx)
|
||||
|
||||
_, err = tc.queryService.QueryData(ctx, tc.signedInUser, true, reqDTO)
|
||||
require.NoError(t, err)
|
||||
|
||||
// response headers should be merged
|
||||
header := contexthandler.FromContext(ctx).Resp.Header()
|
||||
assert.Len(t, header.Values("test"), 2)
|
||||
})
|
||||
|
||||
t.Run("can query multiple datasources with an expression present", func(t *testing.T) {
|
||||
@@ -527,9 +545,13 @@ func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasource
|
||||
type fakePluginClient struct {
|
||||
plugins.Client
|
||||
req *backend.QueryDataRequest
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (c *fakePluginClient) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.req = req
|
||||
|
||||
// If an expression query ends up getting directly queried, we want it to return an error in our test.
|
||||
@@ -541,5 +563,9 @@ func (c *fakePluginClient) QueryData(ctx context.Context, req *backend.QueryData
|
||||
return nil, errors.New("plugin client failed")
|
||||
}
|
||||
|
||||
if reqCtx := contexthandler.FromContext(ctx); reqCtx != nil && reqCtx.Resp != nil {
|
||||
reqCtx.Resp.Header().Add("test", fmt.Sprintf("header-%d", time.Now().Nanosecond()))
|
||||
}
|
||||
|
||||
return &backend.QueryDataResponse{Responses: make(backend.Responses)}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user