(ctx context.Context, qrReq *frontendv2pb.QueryResultRequest)
| 267 | } |
| 268 | |
| 269 | func (f *Frontend) QueryResult(ctx context.Context, qrReq *frontendv2pb.QueryResultRequest) (*frontendv2pb.QueryResultResponse, error) { |
| 270 | tenantIDs, err := users.TenantIDs(ctx) |
| 271 | if err != nil { |
| 272 | return nil, err |
| 273 | } |
| 274 | userID := users.JoinTenantIDs(tenantIDs) |
| 275 | |
| 276 | req := f.requests.get(qrReq.QueryID) |
| 277 | // It is possible that some old response belonging to different user was received, if frontend has restarted. |
| 278 | // To avoid leaking query results between users, we verify the user here. |
| 279 | // To avoid mixing results from different queries, we randomize queryID counter on start. |
| 280 | if req != nil && req.userID == userID { |
| 281 | select { |
| 282 | case req.response <- qrReq: |
| 283 | // Should always be possible, unless QueryResult is called multiple times with the same queryID. |
| 284 | default: |
| 285 | level.Warn(f.log).Log("msg", "failed to write query result to the response channel", "queryID", qrReq.QueryID, "user", userID) |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | return &frontendv2pb.QueryResultResponse{}, nil |
| 290 | } |
| 291 | |
| 292 | // CheckReady determines if the query frontend is ready. Function parameters/return |
| 293 | // chosen to match the same method in the ingester |
nothing calls this directly
no test coverage detected