diff --git a/main.go b/main.go index e2b0d69..46235d0 100644 --- a/main.go +++ b/main.go @@ -5,32 +5,36 @@ import ( "fmt" "github.com/kordondev/meeting/throttling" "net/http" + "sync" "time" ) -const burstLimit = 2 +const burstLimit = 3 +const rateLimit = time.Second * 3 +const correctResult = "12" func main() { ctx := context.Background() - throttles := make(map[string]context.Context) // use sync map + var throttles sync.Map http.HandleFunc("/", serveIndexFile) http.HandleFunc("/input.txt", serveInputFile) http.HandleFunc("/result", func(w http.ResponseWriter, r *http.Request) { - cctxV, ok := throttles[r.RemoteAddr] + cctxV, ok := getThrottleContext(&throttles, r.RemoteAddr) + if !ok { cctx, cancel := context.WithCancel(ctx) - throttle := throttling.CreateThrottle(cctx, burstLimit) + throttle := throttling.CreateThrottle(cctx, burstLimit, rateLimit) a := throttleWithCancel{ throttle: throttle, cancel: cancel, } cctxV = context.WithValue(ctx, "throttle", a) - throttles[r.RemoteAddr] = cctxV + throttles.Store(r.RemoteAddr, cctxV) go func() { time.Sleep(time.Minute * 20) - delete(throttles, r.RemoteAddr) + throttles.Delete(r.RemoteAddr) cancel() }() } @@ -50,18 +54,18 @@ type throttleWithCancel struct { } func serveIndexFile(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, "static/index-with-text.html") + http.ServeFile(w, r, "static/index.html") } func serveInputFile(w http.ResponseWriter, r *http.Request) { - fmt.Println(r.RemoteAddr) + fmt.Println(time.Now(), "Load input file", r.RemoteAddr) http.ServeFile(w, r, "static/input.txt") } func tryResult(ctx context.Context, w http.ResponseWriter, r *http.Request) { - clientIP := r.RemoteAddr clientResult := r.URL.Query().Get("result") - fmt.Println(clientIP, "called with:", clientResult) + name := r.URL.Query().Get("name") + fmt.Println(time.Now(), "Submit result", clientResult, r.RemoteAddr, name) throttle := ctx.Value("throttle").(throttleWithCancel).throttle payload := throttling.Payload{ R: r, @@ -79,9 +83,19 @@ func (*CheckResult) Call(payload *throttling.Payload) { w := payload.W r := payload.R - fmt.Println("Serve now") - if payload.ClientResult == "12" { + fmt.Println(time.Now(), "Serve now for", r.RemoteAddr) + if payload.ClientResult == correctResult { http.ServeFile(w, r, "static/success.html") + return } http.ServeFile(w, r, "static/fail.html") } + +func getThrottleContext(throttles *sync.Map, RemoteAddr string) (context.Context, bool) { + ctx1, ok := throttles.Load(RemoteAddr) + if !ok { + return nil, ok + } + return ctx1.(context.Context), true + +} diff --git a/static/fail.html b/static/fail.html index 3bc86f3..9475fdb 100644 --- a/static/fail.html +++ b/static/fail.html @@ -5,8 +5,8 @@
+
+
Leider nicht die richtige Antwort. Versuch es erneut.
\ No newline at end of file diff --git a/static/index-with-text.html b/static/index-with-text.html deleted file mode 100644 index 946bed4..0000000 --- a/static/index-with-text.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -Die Türsteher veranstallten ein Schere-Stein-Papier-Turnier zwischen den Wartenden. Nur die Besten dürfen zu dem Treffen.
-Schere-Stein-Papier ist ein Spiel zwischen zwei Spielern. Jedes Spiel besteht aus mehreren Runden; in jeder Runde wählen die Spieler gleichzeitig eine der Optionen Stein, Papier oder Schere durch eine Handgeste. Dann wird ein Gewinner für die Runde bestimmt: Stein schlägt Schere, Schere schlägt Papier und Papier schlägt Stein. Wählen beide Spieler die gleiche Form, endet die Runde unentschieden.
-Plötzlich bekommst du von einer unbekannten Nummer: Einen verschlüsselten Strategie-Leitfaden (deine Puzzle-Eingabe), von dem gesagt wird, dass er dir sicher helfen wird zu gewinnen. „Die erste Spalte zeigt, was dein Gegner spielen wird: A steht für Stein, B für Papier und C für Schere. Die zweite Spalte—“ Plötzlich ein Funkloch und der Rest der Nachricht fehlt.
-Du folgerst, dass die zweite Spalte das zeigt, was du als Reaktion spielen solltest: A für Stein, B für Papier und C für Schere. Immer zu gewinnen wäre verdächtig, also müssen die Antworten sorgfältig gewählt worden sein.
-Der Gewinner des gesamten Turniers ist der Spieler mit der höchsten Punktzahl. Deine Gesamtpunktzahl ist die Summe deiner Punkte für jede Runde. Die Punktzahl für eine einzelne Runde setzt sich zusammen aus der Punktzahl für die gewählte Form (1 für Stein, 2 für Papier und 3 für Schere) plus der Punktzahl für das Ergebnis der Runde (0, wenn du verloren hast, 3, wenn die Runde unentschieden endete, und 6, wenn du gewonnen hast).
-Da du dir nicht sicher sein kannst, ob dir die unbekannte Person wirklich helfen will oder dich täuschen möchte, solltest du die Punktzahl berechnen, die du erreichen würdest, wenn du den Strategie-Leitfaden befolgst.
-Zum Beispiel, nehmen wir an, du bekommst den folgenden Strategie-Leitfaden:
--A B -B A -C C --
Dieser Strategie-Leitfaden sagt Folgendes voraus und empfiehlt:
-In diesem Beispiel würdest du, wenn du dem Strategie-Leitfaden folgst, eine Gesamtpunktzahl von 15 erreichen (8 + 1 + 6).
-Was wäre deine Gesamtpunktzahl, wenn alles genau nach dem Strategie-Leitfaden verläuft?
- - - -Ich hoffe, diese Übersetzung hilft dir weiter!
- - - - \ No newline at end of file diff --git a/static/index.html b/static/index.html index e121743..2de6dd1 100644 --- a/static/index.html +++ b/static/index.html @@ -5,15 +5,38 @@Die Türsteher veranstallten ein Schere-Stein-Papier-Turnier zwischen den Wartenden. Nur die Besten dürfen zu dem Treffen.
+Schere-Stein-Papier ist ein Spiel zwischen zwei Spielern. Jedes Spiel besteht aus mehreren Runden; in jeder Runde wählen die Spieler gleichzeitig eine der Optionen Stein, Papier oder Schere durch eine Handgeste. Dann wird ein Gewinner für die Runde bestimmt: Stein schlägt Schere, Schere schlägt Papier und Papier schlägt Stein. Wählen beide Spieler die gleiche Form, endet die Runde unentschieden.
+Plötzlich bekommst du von einer unbekannten Nummer: Einen verschlüsselten Strategie-Leitfaden (deine Puzzle-Eingabe), von dem gesagt wird, dass er dir sicher helfen wird zu gewinnen. „Die erste Spalte zeigt, was dein Gegner spielen wird: A steht für Stein, B für Papier und C für Schere. Die zweite Spalte—“ Plötzlich ein Funkloch und der Rest der Nachricht fehlt.
+Du folgerst, dass die zweite Spalte das zeigt, was du als Reaktion spielen solltest: A für Stein, B für Papier und C für Schere. Immer zu gewinnen wäre verdächtig, also müssen die Antworten sorgfältig gewählt worden sein.
+Der Gewinner des gesamten Turniers ist der Spieler mit der höchsten Punktzahl. Deine Gesamtpunktzahl ist die Summe deiner Punkte für jede Runde. Die Punktzahl für eine einzelne Runde setzt sich zusammen aus der Punktzahl für die gewählte Form (1 für Stein, 2 für Papier und 3 für Schere) plus der Punktzahl für das Ergebnis der Runde (0, wenn du verloren hast, 3, wenn die Runde unentschieden endete, und 6, wenn du gewonnen hast).
+Da du dir nicht sicher sein kannst, ob dir die unbekannte Person wirklich helfen will oder dich täuschen möchte, solltest du die Punktzahl berechnen, die du erreichen würdest, wenn du den Strategie-Leitfaden befolgst.
+Zum Beispiel, nehmen wir an, du bekommst den folgenden Strategie-Leitfaden:
++A B +B A +C C ++
Dieser Strategie-Leitfaden sagt Folgendes voraus und empfiehlt:
+In diesem Beispiel würdest du, wenn du dem Strategie-Leitfaden folgst, eine Gesamtpunktzahl von 15 erreichen (8 + 1 + 6).
+Was wäre deine Gesamtpunktzahl, wenn alles genau nach dem Strategie-Leitfaden verläuft?
- \ No newline at end of file diff --git a/static/success.html b/static/success.html index 4f21879..3b767bb 100644 --- a/static/success.html +++ b/static/success.html @@ -5,10 +5,15 @@
Schön, dass du es geschafft hast. Ich hoffe, du hattest etwas Spaß und hast nicht allzu lange gebraucht. Aber es hat sich gelohnt.
+Hier kannst du dich zurückmelden. Bitte bis zum 24.12. ausfüllen.
++ Viele Grüße + Daniel & Arne +
+PS: Am 3.1. gibt es keine Türsteher mehr.
\ No newline at end of file diff --git a/throttling/rateLimit.go b/throttling/rateLimit.go index 2ba2b43..3214f70 100644 --- a/throttling/rateLimit.go +++ b/throttling/rateLimit.go @@ -7,8 +7,6 @@ import ( "time" ) -const rateLimit = time.Second * 3 // a call each 3 second - // Client is an interface that calls something with a payload. type Client interface { Call(*Payload) @@ -28,7 +26,7 @@ func CallFunction(ctx context.Context, client Client, payload *Payload, throttle client.Call(payload) } -func CreateThrottle(ctx context.Context, burstLimit int) <-chan time.Time { +func CreateThrottle(ctx context.Context, burstLimit int, rateLimit time.Duration) <-chan time.Time { throttle := make(chan time.Time, burstLimit) for i := 0; i < burstLimit; i++ { throttle <- time.Now() @@ -50,7 +48,6 @@ func CreateThrottle(ctx context.Context, burstLimit int) <-chan time.Time { } default: { - fmt.Println("Dropping bucket") } } }