2019-04-15 00:52:10 +03:00
|
|
|
package queue
|
|
|
|
|
|
|
|
import (
|
2019-04-15 01:32:22 +03:00
|
|
|
"strings"
|
2019-04-15 00:52:10 +03:00
|
|
|
"sync"
|
2019-04-15 01:32:22 +03:00
|
|
|
"time"
|
2019-04-15 00:52:10 +03:00
|
|
|
|
|
|
|
"github.com/elyby/chrly/api/mojang"
|
|
|
|
)
|
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
var onFirstCall sync.Once
|
|
|
|
var queue = jobsQueue{}
|
2019-04-15 00:52:10 +03:00
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
func ScheduleTexturesForUsername(username string) (resultChan chan *mojang.SignedTexturesResponse) {
|
|
|
|
onFirstCall.Do(func() {
|
|
|
|
queue.New()
|
|
|
|
startQueue()
|
|
|
|
})
|
|
|
|
|
|
|
|
// TODO: prevent of adding the same username more than once
|
|
|
|
queue.Enqueue(&jobItem{username, resultChan})
|
2019-04-15 00:52:10 +03:00
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
return
|
2019-04-15 00:52:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
func startQueue() {
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
start := time.Now()
|
|
|
|
queueRound()
|
|
|
|
time.Sleep(time.Second - time.Since(start))
|
|
|
|
}
|
|
|
|
}()
|
2019-04-15 00:52:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
func queueRound() {
|
|
|
|
if queue.IsEmpty() {
|
|
|
|
return
|
2019-04-15 00:52:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
jobs := queue.Dequeue(100)
|
|
|
|
var usernames []string
|
|
|
|
for _, job := range jobs {
|
|
|
|
usernames = append(usernames, job.Username)
|
|
|
|
}
|
2019-04-15 00:52:10 +03:00
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
profiles, err := mojang.UsernamesToUuids(usernames)
|
|
|
|
switch err.(type) {
|
|
|
|
case *mojang.TooManyRequestsError:
|
|
|
|
for _, job := range jobs {
|
|
|
|
job.RespondTo <- nil
|
|
|
|
}
|
2019-04-15 00:52:10 +03:00
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
return
|
|
|
|
case error:
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for _, job := range jobs {
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
var result *mojang.SignedTexturesResponse
|
|
|
|
shouldCache := true
|
|
|
|
var uuid string
|
|
|
|
for _, profile := range profiles {
|
|
|
|
if strings.EqualFold(job.Username, profile.Name) {
|
|
|
|
uuid = profile.Id
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if uuid != "" {
|
|
|
|
result, err = mojang.UuidToTextures(uuid, true)
|
|
|
|
if err != nil {
|
|
|
|
if _, ok := err.(*mojang.TooManyRequestsError); !ok {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldCache = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wg.Done()
|
|
|
|
|
|
|
|
job.RespondTo <- result
|
|
|
|
|
|
|
|
if shouldCache {
|
|
|
|
// TODO: store result to cache
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
2019-04-15 00:52:10 +03:00
|
|
|
|
2019-04-15 01:32:22 +03:00
|
|
|
wg.Wait()
|
2019-04-15 00:52:10 +03:00
|
|
|
}
|