2016-06-02 12:16:02 +00:00
|
|
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors.
|
2015-09-07 08:21:23 +00:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
2020-04-04 07:39:13 +00:00
|
|
|
"net/http"
|
2015-09-07 08:21:23 +00:00
|
|
|
"net/url"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2020-04-04 07:39:13 +00:00
|
|
|
const (
|
|
|
|
httpStatusEnhanceYourCalm = 429
|
|
|
|
)
|
|
|
|
|
2016-08-23 06:43:27 +00:00
|
|
|
func poolHandler(pool string, uri *url.URL, mapping mapping) {
|
2015-09-21 21:33:29 +00:00
|
|
|
if debug {
|
|
|
|
log.Println("Joining", pool)
|
|
|
|
}
|
2015-09-07 08:21:23 +00:00
|
|
|
for {
|
2016-08-23 06:43:27 +00:00
|
|
|
uriCopy := *uri
|
|
|
|
uriCopy.Host = mapping.Address().String()
|
|
|
|
|
2015-09-07 08:21:23 +00:00
|
|
|
var b bytes.Buffer
|
|
|
|
json.NewEncoder(&b).Encode(struct {
|
|
|
|
URL string `json:"url"`
|
|
|
|
}{
|
2016-08-23 06:43:27 +00:00
|
|
|
uriCopy.String(),
|
2015-09-07 08:21:23 +00:00
|
|
|
})
|
|
|
|
|
2018-02-21 14:56:04 +00:00
|
|
|
resp, err := httpClient.Post(pool, "application/json", &b)
|
2015-09-07 08:21:23 +00:00
|
|
|
if err != nil {
|
2020-04-04 07:39:13 +00:00
|
|
|
log.Printf("Error joining pool %v: HTTP request: %v", pool, err)
|
2015-09-07 08:21:23 +00:00
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
2020-04-04 07:39:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bs, err := ioutil.ReadAll(resp.Body)
|
|
|
|
resp.Body.Close()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error joining pool %v: reading response: %v", pool, err)
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
switch resp.StatusCode {
|
|
|
|
case http.StatusOK:
|
2015-09-07 08:21:23 +00:00
|
|
|
var x struct {
|
|
|
|
EvictionIn time.Duration `json:"evictionIn"`
|
|
|
|
}
|
2020-06-10 09:26:09 +00:00
|
|
|
if err := json.Unmarshal(bs, &x); err == nil {
|
2015-09-07 08:21:23 +00:00
|
|
|
rejoin := x.EvictionIn - (x.EvictionIn / 5)
|
2020-04-04 07:39:13 +00:00
|
|
|
log.Printf("Joined pool %s, rejoining in %v", pool, rejoin)
|
2015-09-07 08:21:23 +00:00
|
|
|
time.Sleep(rejoin)
|
|
|
|
continue
|
2015-11-06 12:58:44 +00:00
|
|
|
} else {
|
2020-04-04 07:39:13 +00:00
|
|
|
log.Printf("Joined pool %s, failed to deserialize response: %v", pool, err)
|
2015-09-07 08:21:23 +00:00
|
|
|
}
|
2020-04-04 07:39:13 +00:00
|
|
|
|
|
|
|
case http.StatusInternalServerError:
|
|
|
|
log.Printf("Failed to join %v: server error", pool)
|
|
|
|
log.Printf("Response data: %s", bs)
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
|
|
|
|
|
|
|
case http.StatusBadRequest:
|
|
|
|
log.Printf("Failed to join %v: request or check error", pool)
|
|
|
|
log.Printf("Response data: %s", bs)
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
|
|
|
|
|
|
|
case httpStatusEnhanceYourCalm:
|
|
|
|
log.Printf("Failed to join %v: under load (rate limiting)", pool)
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
|
|
|
|
|
|
|
case http.StatusUnauthorized:
|
|
|
|
log.Printf("Failed to join %v: IP address not matching external address", pool)
|
|
|
|
log.Println("Aborting")
|
|
|
|
return
|
|
|
|
|
|
|
|
default:
|
|
|
|
log.Printf("Failed to join %v: unexpected status code from server: %d", pool, resp.StatusCode)
|
|
|
|
log.Printf("Response data: %s", bs)
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
continue
|
2015-09-07 08:21:23 +00:00
|
|
|
}
|
2020-04-04 07:39:13 +00:00
|
|
|
|
2015-09-07 08:21:23 +00:00
|
|
|
time.Sleep(time.Hour)
|
|
|
|
}
|
|
|
|
}
|