I want to pass the value to the channel when there is a http request occurred, I got this code:
package main
import (
"io"
"net/http"
"time"
)
var channel1 chan int
func main() {
channel1 := make(chan int)
go func() {
select {
case <-channel1:
fmt.Println("Channel1")
case <-time.After(time.Second * 100):
fmt.Println("Timeout")
}
}()
http.HandleFunc("/", handleMain)
http.ListenAndServe("localhost:8080", nil)
}
func handleMain(w http.ResponseWriter, r *http.Request) {
channel1 <- 1
io.WriteString(w, "Hello from a HandleFunc!")
}
This freezes on channel1 <-1 when I do my request to "/", why is so, and how can I achieve what I want?
Got it, the error was in channel initialization, I should not write channel1:=make(chan int)
, instead used channel1=make(chan int)
, everything worked!
Yes it is possible. One thing to consider is the lifecycle of the data that your sending on the channel. Currently the channel is unbuffered so that a send:
channel1 <- 1
Requires a receive:
case <-channel1:
Which means that the writes will queue up and block until they are ready to be handled. The problem with this is that as soon as the receive occurs the HTTP handler will complete, with a 200 suggesting to the client that the operation was OK
and successful. The issue is that the other go routine with the receive may not be complete since it executes concurrently to the handler goroutine. The ownership of the data has been transferred to another goroutine. So what happens if the other goroutine errors but the client thinks that the operation has completed successfully?
This becomes more apparent if the channel is buffered, where the http handler goroutine sends immediately and then returns. There's a wide range of solutions to this problem but if not addressed it could lead to subtle data loss and logical errors.