github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/ext/dsort/bcast.go (about)

     1  // Package dsort provides distributed massively parallel resharding for very large datasets.
     2  /*
     3   * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
     4   */
     5  package dsort
     6  
     7  import (
     8  	"io"
     9  	"net/http"
    10  	"net/url"
    11  	"sync"
    12  
    13  	"github.com/NVIDIA/aistore/cmn"
    14  	"github.com/NVIDIA/aistore/cmn/cos"
    15  	"github.com/NVIDIA/aistore/core/meta"
    16  )
    17  
    18  //
    19  // common code used by proxy _and_ target, both
    20  //
    21  
    22  var bcastClient *http.Client
    23  
    24  func bcast(method, path string, urlParams url.Values, body []byte, smap *meta.Smap, ignore ...*meta.Snode) []response {
    25  	var (
    26  		idx       int
    27  		responses = make([]response, smap.CountActiveTs())
    28  		wg        = &sync.WaitGroup{}
    29  	)
    30  outer:
    31  	for _, node := range smap.Tmap {
    32  		if smap.InMaintOrDecomm(node) {
    33  			continue
    34  		}
    35  		for _, ignoreNode := range ignore {
    36  			if ignoreNode.Eq(node) {
    37  				continue outer
    38  			}
    39  		}
    40  		reqArgs := cmn.HreqArgs{
    41  			Method: method,
    42  			Base:   node.URL(cmn.NetIntraControl),
    43  			Path:   path,
    44  			Query:  urlParams,
    45  			Body:   body,
    46  		}
    47  		wg.Add(1)
    48  		go func(si *meta.Snode, args *cmn.HreqArgs, i int) {
    49  			responses[i] = call(args)
    50  			responses[i].si = si
    51  			wg.Done()
    52  		}(node, &reqArgs, idx)
    53  		idx++
    54  	}
    55  	wg.Wait()
    56  
    57  	return responses[:idx]
    58  }
    59  
    60  func call(reqArgs *cmn.HreqArgs) response {
    61  	req, err := reqArgs.Req()
    62  	if err != nil {
    63  		return response{err: err, statusCode: http.StatusInternalServerError}
    64  	}
    65  
    66  	resp, err := bcastClient.Do(req) //nolint:bodyclose // Closed inside `cos.Close`.
    67  	if err != nil {
    68  		return response{err: err, statusCode: http.StatusInternalServerError}
    69  	}
    70  	out, err := io.ReadAll(resp.Body)
    71  	cos.Close(resp.Body)
    72  	return response{res: out, err: err, statusCode: resp.StatusCode}
    73  }