@@ -254,14 +254,36 @@ func (d *Distributor) doUnary(userID string, w http.ResponseWriter, r *http.Requ
254254 defer sp .Finish ()
255255 // Until we have a mechanism to combine the results from multiple alertmanagers,
256256 // we forward the request to only only of the alertmanagers.
257- amDesc := replicationSet .Instances [rand .Intn (len (replicationSet .Instances ))]
258- resp , err := d .doRequest (ctx , amDesc , req )
259- if err != nil {
260- respondFromError (err , w , logger )
261- return
257+
258+ var instances []ring.InstanceDesc
259+ if req .GetMethod () == "GET" && d .isUnaryReadPath (r .URL .Path ) {
260+ instances = replicationSet .Instances
261+ // Randomize the list of instances to not always query the same one.
262+ rand .Shuffle (len (instances ), func (i , j int ) {
263+ instances [i ], instances [j ] = instances [j ], instances [i ]
264+ })
265+ } else {
266+ //Picking 1 instance at Random for Non-Get Unary Read requests, as shuffling through large number of instances might increase complexity
267+ randN := rand .Intn (len (replicationSet .Instances ))
268+ instances = replicationSet .Instances [randN : randN + 1 ]
262269 }
263270
264- respondFromHTTPGRPCResponse (w , resp )
271+ var lastErr error
272+ for _ , instance := range instances {
273+ resp , err := d .doRequest (ctx , instance , req )
274+ // storing the last error message
275+ if err != nil {
276+ lastErr = err
277+ continue
278+ }
279+ // Return on the first succeeded request
280+ respondFromHTTPGRPCResponse (w , resp )
281+ return
282+ }
283+ // throwing the last error if the for loop finish without succeeding
284+ if lastErr != nil {
285+ respondFromError (lastErr , w , logger )
286+ }
265287}
266288
267289func respondFromError (err error , w http.ResponseWriter , logger log.Logger ) {
0 commit comments