xxxxxxxxxx
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httputil"
"time"
"k8s.io/klog"
)
type OptionsRetryRequest struct {
Retry int `json:"retry"`
Throtle int64 `json:"throtle"`
Body interface{} `json:"body"`
Headers map[string]string `json:"headers"`
}
func HttpRetryRequest(url string, method string, IsJson bool, options *OptionsRetryRequest) ([]byte, error) {
var (
count int = 1
res *http.Response = &http.Response{}
err error = nil
body []byte = nil
blocking chan bool = make(chan bool, 1)
client *http.Client = &http.Client{}
)
tick := time.NewTicker(time.Duration(options.Throtle/1000) * time.Second)
if IsJson && options.Body != nil {
bodyByte, err := json.Marshal(&options.Body)
if err != nil {
return nil, err
}
body = bodyByte
} else if !IsJson && options.Body != nil {
body = []byte(fmt.Sprintf("%s", options.Body))
}
for range tick.C {
req, err := http.NewRequest(method, url, bytes.NewReader(body))
if err != nil {
return nil, err
}
if _, err := httpDumpReq(req); err != nil {
return nil, err
}
if options.Headers != nil {
for k, v := range options.Headers {
req.Header.Set(k, v)
}
}
res, err = client.Do(req)
if err != nil {
return nil, err
}
if _, err := httpDumpRes(res); err != nil {
return nil, err
}
if count == options.Retry {
blocking <- true
tick.Stop()
break
}
count++
}
if err != nil {
return nil, err
}
resByte, err := io.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
return nil, err
}
<-blocking
return resByte, nil
}
func httpDumpReq(req *http.Request) ([]byte, error) {
reqDump, err := httputil.DumpRequest(req, true)
if err != nil {
return nil, err
}
klog.Info("====================== HTTP DUMP REQUEST START ======================")
klog.Infof("====================== HTTP DUMP REQUEST OUTPUT ==================== \n\n%s", string(reqDump))
klog.Info("====================== HTTP DUMP REQUEST END ========================")
return reqDump, nil
}
func httpDumpRes(res *http.Response) ([]byte, error) {
resDump, err := httputil.DumpResponse(res, true)
if err != nil {
return nil, err
}
klog.Info("====================== HTTP DUMP RESPONSE START ======================")
klog.Infof("===================== HTTP DUMP RESPONSE OUTPUT ====================== \n\n%s", string(resDump))
klog.Info("====================== HTTP DUMP RESPONSE END ========================")
return resDump, nil
}
xxxxxxxxxx
package main
import (
"fmt"
"io"
"log"
"math"
"net/http"
"sync"
"time"
)
func main() {
var (
baseInterval int = 2
baseIntervalTarget int = 100 // 10800
retryRequestTarget int = 300
tick *time.Ticker = time.NewTicker(time.Second * time.Duration(baseInterval))
store []interface{} = []interface{}{}
interval int = 0
increment int = 0
retryRequest int = 0
release chan bool = make(chan bool, 1)
untilRelease chan bool = make(chan bool, 1)
untilInterval int = 60 // 86400
)
for range tick.C {
startTime := time.Now().Second()
fmt.Printf("\n")
fmt.Println("TIME NOW IN SECOND: ", startTime)
n := int(math.Floor(float64((baseInterval + startTime) / 10)))
interval += int(n)
store = append(store, interval)
increment++
distinct := Distinct(store)
fmt.Printf("\n")
fmt.Println("SEQUENCES DATA: ", distinct)
fmt.Println("INCREMENT DATA: ", increment)
fmt.Printf("\n")
position := IndexOf(increment, distinct)
if position != -1 {
retryRequest++
HttpRequest(release)
fmt.Println("SEQUENCES DATA MATCH: ", true)
fmt.Println("RETRY REQUEST: ", retryRequest)
} else {
fmt.Println("SEQUENCES DATA NOT MATCH: ", false)
fmt.Println("NO RETRY REQUEST: ", 0)
}
sumInterval := math.Ceil(float64(Reduce(SliceInterfaceToSliceInt(distinct)) / 10))
fmt.Printf("\n")
log.Println("INTERVAL: ", sumInterval)
if c := int64(sumInterval); c >= int64(baseIntervalTarget) {
fmt.Printf("\n")
fmt.Println("STOP BY INTERVAL: ", c)
interval = 0
increment = 0
retryRequest = 0
store = nil
time.AfterFunc(time.Duration(time.Second*time.Duration(untilInterval)), func() {
untilRelease <- true
})
<-untilRelease
} else if c := retryRequest; c >= retryRequestTarget {
fmt.Printf("\n")
fmt.Println("STOP BY RETRY REQUEST: ", c)
interval = 0
increment = 0
retryRequest = 0
store = nil
time.AfterFunc(time.Duration(time.Second*time.Duration(untilInterval)), func() {
untilRelease <- true
})
<-untilRelease
}
}
}
func HttpRequest(release chan bool) bool {
res, err := http.Get("https://jsonplaceholder.typicode.com/users")
if err != nil {
release <- true
log.Fatal(err.Error())
}
defer res.Body.Close()
bodyByte, err := io.ReadAll(res.Body)
if err != nil {
release <- true
log.Fatal(err.Error())
}
if len(bodyByte) > 0 {
release <- true
}
<-release
return true
}
func IndexOf(element interface{}, data []interface{}) interface{} {
for k, v := range data {
if element == v {
return k
}
}
return -1
}
func Distinct(data []interface{}) []interface{} {
uniqueNumbers := make(map[interface{}]bool)
result := []interface{}{}
for _, num := range data {
if !uniqueNumbers[num] {
uniqueNumbers[num] = true
result = append(result, num)
}
}
return result
}
func Reduce(data []int) int64 {
var sum int64
for i := 0; i < len(data); i++ {
sum += int64(data[i])
}
return sum
}
func SliceInterfaceToSliceInt(data []interface{}) []int {
numbers := []int{}
mutex := &sync.RWMutex{}
for _, n := range data {
mutex.Lock()
numbers = append(numbers, n.(int))
mutex.Unlock()
}
return numbers
}