diff --git a/exporter.go b/exporter.go index dab1b24..5e7b761 100644 --- a/exporter.go +++ b/exporter.go @@ -824,7 +824,10 @@ func (e *Exporter) collectHotspotRewardsMetrics(wg *sync.WaitGroup, ch chan<- pr } func main() { - fApiUrl := flag.String("apiUrl", "https://api.helium.io", "The helium api url") + var err error + + fApiUrl := flag.String("apiUrl", "https://helium-api.stakejoy.com", "The helium api url") + fApiTimeout := flag.String("apiTimeout", "10s", "The request timeout to the helium api.") fHeliumAccounts := flag.String("accounts", "", "A comma-delimited list of helium accounts to scrape (optional)") fMetricsPath := flag.String("metricpath", "/metrics", "The metrics path") fListenAddress := flag.String("listenAddress", "0.0.0.0", "The http server listen address") @@ -832,6 +835,11 @@ func main() { flag.Parse() heliumapi.ApiUrl = *fApiUrl + heliumapi.ApiTimeout, err = time.ParseDuration(*fApiTimeout) + if err != nil { + log.Fatalf("failed to parse apitTimeout: %s", err.Error()) + } + heliumAccounts := strings.Split(*fHeliumAccounts, ",") serverAddr := *fListenAddress + ":" + *fListenPort diff --git a/heliumapi/query.go b/heliumapi/query.go index fd26f92..addb6ee 100644 --- a/heliumapi/query.go +++ b/heliumapi/query.go @@ -1,20 +1,24 @@ package heliumapi import ( + "context" "encoding/json" "fmt" "io/ioutil" "net/http" + "time" ) var ( - ApiUrl = "https://api.helium.io" - client = &http.Client{} + ApiUrl = "https://api.helium.io" + ApiTimeout = time.Duration(10 * time.Second) + client = &http.Client{} ) // createGetRequest create a GET request to the helium api -func createGetRequest(path string, params map[string]string) (*http.Request, error) { - req, err := http.NewRequest("GET", fmt.Sprintf("%s%s", ApiUrl, path), nil) +func createGetRequest(path string, params map[string]string) (*http.Request, *context.CancelFunc, error) { + ctx, ctxCancel := context.WithTimeout(context.Background(), ApiTimeout) + req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s%s", ApiUrl, path), nil) // setup headers req.Header.Add("Accept", "application/json") @@ -26,12 +30,13 @@ func createGetRequest(path string, params map[string]string) (*http.Request, err query.Add(k, v) } if err != nil { - return nil, err + defer ctxCancel() + return nil, nil, err } req.URL.RawQuery = query.Encode() } - return req, err + return req, &ctxCancel, err } // getHeliumApi query a regular helium api endpoint @@ -41,10 +46,11 @@ func getHeliumApi(path string, params *map[string]string) ([]byte, error) { params = &map[string]string{} } - req, err := createGetRequest(path, *params) + req, ctxCancel, err := createGetRequest(path, *params) if err != nil { return nil, fmt.Errorf("failed to create query request %v: %v", path, err) } + defer (*ctxCancel)() // query the api // log.Printf("querying %v", req.URL.String()) @@ -83,10 +89,11 @@ func getHeliumApiWithCursor(path string, params *map[string]string) ([][]byte, e res := [][]byte{} respCursor := ResponseWithCursor{} - req, err := createGetRequest(path, *params) + req, ctxCancel, err := createGetRequest(path, *params) if err != nil { return nil, fmt.Errorf("failed to create query request %v: %v", path, err) } + defer (*ctxCancel)() for { // query the api @@ -119,10 +126,11 @@ func getHeliumApiWithCursor(path string, params *map[string]string) ([][]byte, e // continue querying until there is no longer a cursor if respCursor.Cursor != "" { params = &map[string]string{"cursor": respCursor.Cursor} - req, err = createGetRequest(path, *params) + req, ctxCancel, err = createGetRequest(path, *params) if err != nil { return nil, fmt.Errorf("failed to create query request %v: %v", req.URL.String(), err) } + defer (*ctxCancel)() } else { break }