GoLang Api läd response nicht?
Ich möchte eine API in GoLang schreiben die mit einem Login verknüpft ist. Wenn der User auf der Seite den Loginbutton klickt, wird eine Anfrage an die API geschickt. Diese soll dann so lange blockieren, bis die Daten von der login Funktion zur Verfügung stehen. Die Login Funktion wird dabei erst am Ende des Logins aufgerufen, der unterschiedlich lange dauern kann. Jetzt das folgende Problem - mache ich eine Anfrage an die API NACHDEM der Login beendet wurde, funktioniert alles; mache ich die Anfrage aber WÄHREND/VOR des/dem Logins dann kommt keine Response von der API. Sie wird also irgendwie dauerhaft blockiert.
func login(w http.ResponseWriter, r *http.Request) {
go func(){
// Verarbeitung von Daten
receiver := <- channel
channel <- Daten
}()
http.Redirect(w, r, "http://localhost:8080", http.StatusFound)
}
func apiFunc(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
ques := vars["category"]
wg.Add(1)
go func() {
channel <- "Daten ID"
loginData := <- channel
switch ques {
case "Daten":
// Verarbeitung von Daten
json.NewEncoder(w).Encode(Daten)
wg.Done()
}
}()
wg.Wait()
}
1 Antwort
Das Problem ist dass du in der apiFunc funktion die wg.Wait() funktion aufrufst. Dadurch kann die Anfrage verzögert werden.
Hier habe ich es korrigiert:
var loginChannel = make(chan string)
func login(w http.ResponseWriter, r *http.Request) {
go func() {
time.Sleep(3 * time.Second) // Simuliert den Login-Prozess
loginChannel <- "Daten"
}()
http.Redirect(w, r, "http://localhost:8080", http.StatusFound)
}
func apiFunc(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
ques := vars["category"]
switch ques {
case "Daten":
loginData := <-loginChannel
json.NewEncoder(w).Encode(loginData)
}
}
Ok dann nutzen wir ein Syncron Muster in einem Kanal:
var loginChannel = make(chan string)
func login(w http.ResponseWriter, r *http.Request) {
go func() {
time.Sleep(3 * time.Second) // Simuliert den Login-Prozess
loginChannel <- "Daten"
}()
http.Redirect(w, r, "http://localhost:8080", http.StatusFound)
}
func apiFunc(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
ques := vars["category"]
switch ques {
case "Daten":
loginData := <-loginChannel
json.NewEncoder(w).Encode(loginData)
}
}
Sry hier der richtige:
var loginChannel = make(chan string)
func login(w http.ResponseWriter, r *http.Request) {
go func() {
// Verarbeitung von Daten
time.Sleep(3 * time.Second) // Simuliert den Login-Prozess
loginChannel <- "Daten"
}()
http.Redirect(w, r, "http://localhost:8080", http.StatusFound)
}
func apiFunc(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
ques := vars["category"]
switch ques {
case "Daten":
// Hier wird auf den Login gewartet
loginData := <-loginChannel
// Verarbeitung von Daten
json.NewEncoder(w).Encode(loginData)
}
}
Danke dir, das wäre natürlich eine Möglichkeit, das Ziel der API Funktion und damit auch der Grund wieso ich das Ganze probiert hab mit Wg's umzusetzen ist aber, dass die Logindaten DIREKT abgerufen werden sobald der Login abgeschlossen ist - egal wie lange dieser dauert. Durch die einfache Umsetzung mit einem timeout ist das Ganze ja so nicht gegeben...