Skip to content

Commit

Permalink
runner utils and minecraft purge cache
Browse files Browse the repository at this point in the history
  • Loading branch information
LeafHacker committed Oct 13, 2019
1 parent 983972f commit 2c54ea4
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 36 deletions.
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/aws/aws-sdk-go v1.25.9 h1:WtVzerf5wSgPwlTTwl+ktCq/0GCS5MI9ZlLIcjsTr+Q
github.com/aws/aws-sdk-go v1.25.9/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
Expand Down Expand Up @@ -73,6 +74,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f h1:hjzMYz/7Ea1mNKfOnFOfktR0mlA5jqhvywClCMHM/qw=
golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -86,4 +88,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
37 changes: 22 additions & 15 deletions src/api/v1/minecraft.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
"encoding/hex"
"errors"
"fmt"
"github.com/ImpactDevelopment/ImpactServer/src/cloudflare"
"github.com/ImpactDevelopment/ImpactServer/src/util"
"io/ioutil"
"log"
"net/http"
"reflect"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -35,30 +38,34 @@ type (
var loginData map[string]*userInfo

func init() {
err := updateData()
_, err := updateData()
if err != nil {
panic(err)
}
go func() {
ticker := time.NewTicker(5 * time.Minute)
for range ticker.C {
err := updateData()
if err != nil {
log.Println("MC ERROR", err)
}
util.DoRepeatedly(5*time.Minute, func() {
updated, err := updateData()
if err != nil {
log.Println("MC ERROR", err)
}
}()
if updated {
log.Println("MC UPDATE: Updated user info")
cloudflare.PurgeURLs([]string{"https://api.impactclient.net/v1/minecraft/user/info"})
}
})
}

func updateData() error {
func updateData() (updated bool, err error) {
lists, err := getLegacyUUIDLists()
if err != nil {
return err
return
}
loginData = mapLegacyListsToUserInfoList(lists)
// TODO if new data != old data, tell cloudflare to purge this URL lmao
// unironic btw
return nil
newLoginData := mapLegacyListsToUserInfoList(lists)
// reflect.DeepEqual is slow, especially since this map is big
if loginData != nil && !reflect.DeepEqual(newLoginData, loginData) {
loginData = newLoginData
updated = true
}
return
}

// API Handler
Expand Down
10 changes: 0 additions & 10 deletions src/api/v1/minecraft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,4 @@ func TestMapLegacyListsToUserInfoList(t *testing.T) {
for _, role := range fred.Roles {
assert.Contains(t, fredRoleIDs, role.ID)
}

}

func hasRole(info *userInfo, id string) bool {
for _, role := range info.Roles {
if role.ID == id {
return true
}
}
return false
}
21 changes: 10 additions & 11 deletions src/api/v1/motd.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v1

import (
"github.com/ImpactDevelopment/ImpactServer/src/util"
"io/ioutil"
"log"
"net/http"
Expand All @@ -18,24 +19,22 @@ func init() {
var err error
motd, err = fetchMotd()
if err != nil {
panic(err)
log.Println("MOTD ERROR", err)
motd = "Ok, so our MOTD service may or may not be semi-broken right now..."
}
go func() {
ticker := time.NewTicker(3 * time.Minute)
for range ticker.C {
newer, err := fetchMotd()
if err != nil {
log.Println("MOTD ERROR", err)
}
newMotd(newer)
util.DoRepeatedly(3*time.Minute, func() {
newer, err := fetchMotd()
if err != nil {
log.Println("MOTD ERROR", err)
}
}()
newMotd(newer)
})
}

func newMotd(newer string) {
if newer != motd {
motd = newer
log.Println("MOTD UPDATE from", motd, "to", newer)
motd = newer
cloudflare.PurgeURLs([]string{"https://api.impactclient.net/v1/motd"})
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/util/runners.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package util

import (
"time"
)

// DoLater runs a callback function once, after the specified delay
func DoLater(delay time.Duration, f func()) {
go func() {
time.Sleep(delay)
f()
}()
}

// DoRepeatedly runs a callback function after each interval of delay
// it continues until quit is closed
func DoRepeatedly(interval time.Duration, f func()) (quit chan struct{}) {
quit = make(chan struct{})
go func() {
ticker := time.NewTicker(interval)
for range ticker.C {
select {
case <-quit:
return
default:
f()
}
}
}()
return
}
80 changes: 80 additions & 0 deletions src/util/runners_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package util

import (
"github.com/stretchr/testify/assert"
"testing"
"time"
)

func TestDoLater(t *testing.T) {
runs := 0
start := time.Now()
delay := 2 * time.Millisecond

// Test in the goroutine for epic memes, sleep on the main thread to give it time to iterate a bit
DoLater(delay, callback(t, start, delay, &runs))

time.Sleep(100 * delay)
assert.Equal(t, 1, runs, "Should only run once")

// Reset the test to iterate over DoLater a few times
runs = 0
var i int64
for i = 1; i < 100; i++ {
// Give each iteration its own time.Now() just in case this loop crosses into a new ms
// Use an offset delay so they don't all run at once
offsetDelay := time.Duration(i*delay.Milliseconds()) * time.Millisecond
DoLater(offsetDelay, callback(t, time.Now(), delay, &runs))
}
time.Sleep(time.Duration(i*delay.Milliseconds()) * time.Millisecond)
assert.Equal(t, i-1, int64(runs), "Expected the number of runs to match the number of loop iterations")
}

func TestDoRepeatedly(t *testing.T) {
runs := 0
start := time.Now()
interval := 2 * time.Millisecond

// Test in the goroutine for epic memes, sleep on the main thread to give it time to iterate a bit
quit := DoRepeatedly(interval, callback(t, start, interval, &runs))

// Let the test run for approx 100 iterations
// Slow, but ensures the timer doesn't go out of sync after a few iterations
time.Sleep(100 * interval)

// Test closing channel
close(quit)
timesRun := runs
time.Sleep(50 * interval)
assert.Equal(t, timesRun, runs, "Should not run again after closing channel")

// Reset the test to do a couple other bits
runs = 0
timesRun = 0
quit = DoRepeatedly(interval/2, func() {
runs++
})

assert.Equal(t, 0, runs, "Should not run immediately")
time.Sleep(2 * interval)
assert.Greater(t, runs, 1, "Should have run more than once")

// Quit by sending to channel
quit <- struct{}{}
timesRun = runs

time.Sleep(50 * interval)
assert.Equal(t, timesRun, runs, "Should not run again sending to channel")
}

// callback generates a callback function that tests it is run
// at the expected interval(s) after the start time and increments
// `runs` each time the callback is invoked
func callback(t *testing.T, start time.Time, interval time.Duration, runs *int) func() {
return func() {
*runs++
delay := time.Now().Sub(start).Milliseconds()
expect := int64(*runs) * interval.Milliseconds()
assert.Equal(t, expect, delay, "Expected %d delay after %d runs", expect, *runs)
}
}

0 comments on commit 2c54ea4

Please sign in to comment.