meeting/main.go

88 lines
2.0 KiB
Go

package main
import (
"context"
"fmt"
"github.com/kordondev/meeting/throttling"
"net/http"
"slices"
"time"
)
const burstLimit = 2
func main() {
ctx := context.Background()
throttles := make(map[string]context.Context)
calledLastHour := make([]string, 0)
http.HandleFunc("/", serveIndexFile)
http.HandleFunc("/input.txt", serveInputFile)
http.HandleFunc("/result", func(w http.ResponseWriter, r *http.Request) {
cctxV, ok := throttles[r.RemoteAddr]
if !ok {
cctx, cancel := context.WithCancel(ctx)
throttle := throttling.CreateThrottle(cctx, burstLimit)
a := throttleWithCancel{
throttle: throttle,
cancel: cancel,
}
cctxV = context.WithValue(ctx, "throttle", a)
throttles[r.RemoteAddr] = cctxV
}
tryResult(cctxV, w, r, calledLastHour)
})
err := http.ListenAndServe(":3333", nil)
if err != nil {
fmt.Printf("http.ListenAndServe() failed with %s\n", err)
}
}
type throttleWithCancel struct {
throttle <-chan time.Time
cancel context.CancelFunc
}
func serveIndexFile(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "static/index-with-text.html")
}
func serveInputFile(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.RemoteAddr)
http.ServeFile(w, r, "static/input.txt")
}
func tryResult(ctx context.Context, w http.ResponseWriter, r *http.Request, calledLastHour []string) {
clientIP := r.RemoteAddr
clientResult := r.URL.Query().Get("result")
fmt.Println(clientIP, clientResult)
if !slices.Contains(calledLastHour, clientIP) {
calledLastHour = append(calledLastHour, clientIP)
}
throttle := ctx.Value("throttle").(throttleWithCancel).throttle
payload := throttling.Payload{
R: r,
W: w,
ClientResult: clientResult,
}
throttling.CallFunction(ctx, &CheckResult{}, &payload, throttle)
}
type CheckResult struct {
}
func (*CheckResult) Call(payload *throttling.Payload) {
w := payload.W
r := payload.R
fmt.Println("Serve now")
if payload.ClientResult == "12" {
http.ServeFile(w, r, "static/success.html")
}
http.ServeFile(w, r, "static/fail.html")
}