mirror of
https://github.com/TeamPiped/instances-api.git
synced 2024-08-14 23:57:19 +00:00
parallize checks per instance using go routines
This commit is contained in:
parent
2e081e3641
commit
c369f2b7bc
1 changed files with 128 additions and 81 deletions
209
main.go
209
main.go
|
@ -44,108 +44,155 @@ type FrontendConfig struct {
|
|||
S3Enabled bool `json:"s3Enabled"`
|
||||
}
|
||||
|
||||
func testUrl(url string) (*http.Response, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return resp, errors.New(fmt.Sprintf("Invalid response code at %s: %d", url, resp.StatusCode))
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func testCaching(ApiUrl string) (bool, error) {
|
||||
resp, err := testUrl(ApiUrl + "/trending?region=US")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
oldTiming := resp.Header.Get("Server-Timing")
|
||||
resp, err = testUrl(ApiUrl + "/trending?region=US")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
newTiming := resp.Header.Get("Server-Timing")
|
||||
cacheWorking := oldTiming == newTiming
|
||||
return cacheWorking, nil
|
||||
}
|
||||
|
||||
func getConfig(ApiUrl string) (FrontendConfig, error) {
|
||||
resp, err := testUrl(ApiUrl + "/config")
|
||||
if err != nil {
|
||||
return FrontendConfig{}, err
|
||||
}
|
||||
bytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return FrontendConfig{}, err
|
||||
}
|
||||
var config FrontendConfig
|
||||
err = json.Unmarshal(bytes, &config)
|
||||
if err != nil {
|
||||
return FrontendConfig{}, err
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func getInstanceDetails(line string, latest string) (Instance, error) {
|
||||
split := strings.Split(line, "|")
|
||||
if len(split) >= 5 {
|
||||
ApiUrl := strings.TrimSpace(split[1])
|
||||
if len(split) < 5 {
|
||||
return Instance{}, errors.New(fmt.Sprintf("Invalid line: %s", line))
|
||||
}
|
||||
ApiUrl := strings.TrimSpace(split[1])
|
||||
|
||||
resp, err := http.Get(ApiUrl + "/healthcheck")
|
||||
wg := sync.WaitGroup{}
|
||||
errorChannel := make(chan error)
|
||||
// the amount of tests to do
|
||||
wg.Add(6)
|
||||
|
||||
var lastChecked int64
|
||||
var registered int64
|
||||
var config FrontendConfig
|
||||
var hash string
|
||||
var version string
|
||||
var cacheWorking bool
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errorChannel)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if _, err := testUrl(ApiUrl + "/healthcheck"); err != nil {
|
||||
errorChannel <- err
|
||||
return
|
||||
}
|
||||
lastChecked = time.Now().Unix()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
resp, err := testUrl(ApiUrl + "/registered/badge")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
errorChannel <- err
|
||||
return
|
||||
}
|
||||
LastChecked := time.Now().Unix()
|
||||
if resp.StatusCode != 200 {
|
||||
return Instance{}, errors.New("Invalid response code")
|
||||
}
|
||||
resp, err = http.Get(ApiUrl + "/registered/badge")
|
||||
registered, err = strconv.ParseInt(number_re.FindString(resp.Request.URL.Path), 10, 32)
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
errorChannel <- err
|
||||
}
|
||||
registered, err := strconv.ParseInt(number_re.FindString(resp.Request.URL.Path), 10, 32)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
resp, err := testUrl(ApiUrl + "/version")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
resp, err = http.Get(ApiUrl + "/version")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return Instance{}, errors.New("Invalid response code")
|
||||
errorChannel <- err
|
||||
return
|
||||
}
|
||||
buf := new(strings.Builder)
|
||||
_, err = io.Copy(buf, resp.Body)
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
errorChannel <- err
|
||||
return
|
||||
}
|
||||
version := strings.TrimSpace(buf.String())
|
||||
version = strings.TrimSpace(buf.String())
|
||||
version_split := strings.Split(version, "-")
|
||||
hash := version_split[len(version_split)-1]
|
||||
hash = version_split[len(version_split)-1]
|
||||
}()
|
||||
|
||||
resp, err = http.Get(ApiUrl + "/config")
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
var err error
|
||||
config, err = getConfig(ApiUrl)
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return Instance{}, errors.New("Invalid response code")
|
||||
errorChannel <- err
|
||||
}
|
||||
}()
|
||||
|
||||
bytes, err := io.ReadAll(resp.Body)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
var err error
|
||||
cacheWorking, err = testCaching(ApiUrl)
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
|
||||
var config FrontendConfig
|
||||
|
||||
err = json.Unmarshal(bytes, &config)
|
||||
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
|
||||
cache_working := false
|
||||
|
||||
resp, err = http.Get(ApiUrl + "/trending?region=US")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
old_timing := resp.Header.Get("Server-Timing")
|
||||
resp, err = http.Get(ApiUrl + "/trending?region=US")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
new_timing := resp.Header.Get("Server-Timing")
|
||||
if old_timing == new_timing {
|
||||
cache_working = true
|
||||
}
|
||||
}
|
||||
errorChannel <- err
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// check if instance can fetch videos
|
||||
resp, err = http.Get(ApiUrl + "/streams/jNQXAC9IVRw")
|
||||
if err != nil {
|
||||
return Instance{}, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return Instance{}, errors.New("Invalid status code")
|
||||
if _, err := testUrl(ApiUrl + "/streams/jNQXAC9IVRw"); err != nil {
|
||||
errorChannel <- err
|
||||
}
|
||||
}()
|
||||
|
||||
return Instance{
|
||||
Name: strings.TrimSpace(split[0]),
|
||||
ApiUrl: ApiUrl,
|
||||
Locations: strings.TrimSpace(split[2]),
|
||||
Cdn: strings.TrimSpace(split[3]) == "Yes",
|
||||
Registered: int(registered),
|
||||
LastChecked: LastChecked,
|
||||
Version: version,
|
||||
UpToDate: strings.Contains(latest, hash),
|
||||
Cache: cache_working,
|
||||
S3Enabled: config.S3Enabled,
|
||||
}, nil
|
||||
for err := range errorChannel {
|
||||
return Instance{}, err
|
||||
}
|
||||
return Instance{}, errors.New("Invalid line")
|
||||
|
||||
return Instance{
|
||||
Name: strings.TrimSpace(split[0]),
|
||||
ApiUrl: ApiUrl,
|
||||
Locations: strings.TrimSpace(split[2]),
|
||||
Cdn: strings.TrimSpace(split[3]) == "Yes",
|
||||
Registered: int(registered),
|
||||
LastChecked: lastChecked,
|
||||
Version: version,
|
||||
UpToDate: strings.Contains(latest, hash),
|
||||
Cache: cacheWorking,
|
||||
S3Enabled: config.S3Enabled,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func monitorInstances() {
|
||||
|
@ -184,7 +231,6 @@ func monitorInstances() {
|
|||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
|
||||
// parse the response
|
||||
buf := new(strings.Builder)
|
||||
_, err := io.Copy(buf, resp.Body)
|
||||
|
@ -200,20 +246,20 @@ func monitorInstances() {
|
|||
|
||||
wg := sync.WaitGroup{}
|
||||
for index, line := range lines {
|
||||
if index < 3 {
|
||||
fmt.Println(line)
|
||||
// skip first two and last line
|
||||
if index < 2 || index == len(lines)-1 {
|
||||
continue
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(line string) {
|
||||
defer wg.Done()
|
||||
instance, err := getInstanceDetails(line, latest)
|
||||
if err == nil {
|
||||
instances = append(instances, instance)
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
wg.Done()
|
||||
}(line)
|
||||
}
|
||||
wg.Wait()
|
||||
|
@ -237,5 +283,6 @@ func main() {
|
|||
return c.JSON(monitored_instances)
|
||||
})
|
||||
|
||||
fmt.Println("Listening on http://localhost:3000")
|
||||
app.Listen(":3000")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue