| 69 | } |
| 70 | |
| 71 | func (h *readHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 72 | ctx := r.Context() |
| 73 | if err := h.remoteReadGate.Start(ctx); err != nil { |
| 74 | http.Error(w, err.Error(), http.StatusInternalServerError) |
| 75 | return |
| 76 | } |
| 77 | h.queries.Inc() |
| 78 | |
| 79 | defer h.remoteReadGate.Done() |
| 80 | defer h.queries.Dec() |
| 81 | |
| 82 | req, err := DecodeReadRequest(r) |
| 83 | if err != nil { |
| 84 | http.Error(w, err.Error(), http.StatusBadRequest) |
| 85 | return |
| 86 | } |
| 87 | |
| 88 | externalLabels := h.config().GlobalConfig.ExternalLabels.Map() |
| 89 | |
| 90 | sortedExternalLabels := make([]prompb.Label, 0, len(externalLabels)) |
| 91 | for name, value := range externalLabels { |
| 92 | sortedExternalLabels = append(sortedExternalLabels, prompb.Label{ |
| 93 | Name: name, |
| 94 | Value: value, |
| 95 | }) |
| 96 | } |
| 97 | slices.SortFunc(sortedExternalLabels, func(a, b prompb.Label) int { |
| 98 | return strings.Compare(a.Name, b.Name) |
| 99 | }) |
| 100 | |
| 101 | responseType, err := NegotiateResponseType(req.AcceptedResponseTypes) |
| 102 | if err != nil { |
| 103 | http.Error(w, err.Error(), http.StatusBadRequest) |
| 104 | return |
| 105 | } |
| 106 | |
| 107 | switch responseType { |
| 108 | case prompb.ReadRequest_STREAMED_XOR_CHUNKS: |
| 109 | h.remoteReadStreamedXORChunks(ctx, w, req, externalLabels, sortedExternalLabels) |
| 110 | default: |
| 111 | // On empty or unknown types in req.AcceptedResponseTypes we default to non streamed, raw samples response. |
| 112 | h.remoteReadSamples(ctx, w, req, externalLabels, sortedExternalLabels) |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | func (h *readHandler) remoteReadSamples( |
| 117 | ctx context.Context, |