Skip to content

Commit fc4ba54

Browse files
committed
feat: response time goes brrrr
1 parent f9a719d commit fc4ba54

3 files changed

Lines changed: 135 additions & 3 deletions

File tree

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func main() {
8383
}))
8484

8585
routes.RegisterGetDatedDataRoute(r)
86+
routes.RegisterGetBulkDatedDataRoute(r)
8687

8788
util.Logger.Info().Msg("Started Gin HTTP server on :" + os.Getenv("HTTP_PORT"))
8889
if err := r.Run(":" + os.Getenv("HTTP_PORT")); err != nil {

routes/getBulkDatedData.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package routes
2+
3+
import (
4+
"MineTracker/data"
5+
"fmt"
6+
"net/http"
7+
"strings"
8+
"sync"
9+
10+
"github.com/gin-gonic/gin"
11+
)
12+
13+
type serverResult struct {
14+
server string
15+
dataPoints interface{}
16+
step string
17+
err error
18+
}
19+
20+
func RegisterGetBulkDatedDataRoute(r *gin.Engine) {
21+
r.GET("/api/bulk/:servers/:time", func(c *gin.Context) {
22+
serversParam := c.Param("servers")
23+
time := c.Param("time")
24+
25+
servers := strings.Split(serversParam, ",")
26+
27+
// Remove empty servers
28+
var validServers []string
29+
for _, s := range servers {
30+
s = strings.TrimSpace(s)
31+
if s != "" {
32+
validServers = append(validServers, s)
33+
}
34+
}
35+
36+
if len(validServers) == 0 {
37+
c.JSON(http.StatusNotFound, gin.H{"error": "No valid servers provided"})
38+
return
39+
}
40+
41+
// Parallel processing with goroutines
42+
resultChan := make(chan serverResult, len(validServers))
43+
var wg sync.WaitGroup
44+
45+
for _, server := range validServers {
46+
wg.Add(1)
47+
go func(srv string) {
48+
defer wg.Done()
49+
50+
dataPoints, step, err := data.QueryDataPoints(srv, fmt.Sprintf("-%s", time))
51+
52+
resultChan <- serverResult{
53+
server: srv,
54+
dataPoints: dataPoints,
55+
step: step,
56+
err: err,
57+
}
58+
}(server)
59+
}
60+
61+
// Close channel when all goroutines are done
62+
go func() {
63+
wg.Wait()
64+
close(resultChan)
65+
}()
66+
67+
// Collect results
68+
result := make(map[string]interface{})
69+
var commonStep string
70+
71+
for res := range resultChan {
72+
if res.err != nil {
73+
result[res.server] = gin.H{"error": res.err.Error()}
74+
continue
75+
}
76+
77+
if res.dataPoints == nil {
78+
result[res.server] = gin.H{"error": "No data found"}
79+
continue
80+
}
81+
82+
result[res.server] = res.dataPoints
83+
if commonStep == "" {
84+
commonStep = res.step
85+
}
86+
}
87+
88+
c.JSON(http.StatusOK, gin.H{
89+
"data": result,
90+
"step": commonStep,
91+
})
92+
})
93+
}

routes/getDatedData.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,45 @@ import (
44
"MineTracker/data"
55
"fmt"
66
"net/http"
7+
"sync"
8+
"time"
79

810
"github.com/gin-gonic/gin"
911
)
1012

13+
type cacheEntry struct {
14+
data interface{}
15+
step string
16+
timestamp time.Time
17+
}
18+
19+
var (
20+
cache = make(map[string]cacheEntry)
21+
cacheMutex sync.RWMutex
22+
cacheTTL = 30 * time.Second // Cache für 30 Sekunden
23+
)
24+
1125
func RegisterGetDatedDataRoute(r *gin.Engine) {
1226
r.GET("/api/:server/:time", func(c *gin.Context) {
1327
server := c.Param("server")
14-
time := c.Param("time")
28+
timeParam := c.Param("time")
29+
30+
cacheKey := fmt.Sprintf("%s:%s", server, timeParam)
1531

16-
dataPoints, step, err := data.QueryDataPoints(server, fmt.Sprintf("-%s", time))
32+
// Check cache first
33+
cacheMutex.RLock()
34+
if entry, found := cache[cacheKey]; found && time.Since(entry.timestamp) < cacheTTL {
35+
cacheMutex.RUnlock()
36+
c.JSON(http.StatusOK, gin.H{
37+
"data": entry.data,
38+
"step": entry.step,
39+
})
40+
return
41+
}
42+
cacheMutex.RUnlock()
43+
44+
// Query data
45+
dataPoints, step, err := data.QueryDataPoints(server, fmt.Sprintf("-%s", timeParam))
1746

1847
if err != nil {
1948
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -25,7 +54,16 @@ func RegisterGetDatedDataRoute(r *gin.Engine) {
2554
return
2655
}
2756

28-
c.JSON(200, gin.H{
57+
// Store in cache
58+
cacheMutex.Lock()
59+
cache[cacheKey] = cacheEntry{
60+
data: dataPoints,
61+
step: step,
62+
timestamp: time.Now(),
63+
}
64+
cacheMutex.Unlock()
65+
66+
c.JSON(http.StatusOK, gin.H{
2967
"data": dataPoints,
3068
"step": step,
3169
})

0 commit comments

Comments
 (0)