英文:
Golang, unable to have value pushed into 'global' channel when handling HTTP requests
问题
目前我正在开发一个应用程序,处理时间可能从几秒钟到1小时以上不等。因此,在其他请求正在处理时使用通道来阻塞请求似乎是一个不错的选择。以下是我尝试实现的示例,但是我遇到了一个问题,似乎当尝试将数据添加到通道时,我的程序会停止响应(请参见下面的代码)。
package main
import (
"net/http"
"github.com/gorilla/mux"
)
type Request struct {
Id string
}
func ConstructRequest(id string) Request {
return Request{Id: id}
}
var requestChannel chan Request // <- 创建通道的变量
func init() {
r := mux.NewRouter()
r.HandleFunc("/request/{id:[0-9]+}", ProcessRequest).Methods("GET")
http.Handle("/", r)
}
func main() {
// 启动服务器
http.ListenAndServe(":4000", nil)
requestChannel = make(chan Request) // <- 创建通道并赋值给变量
go func() {
for {
request, ok := <-requestChannel
if !ok {
return
}
fmt.Println(request.Id)
}
}()
}
func ProcessRequest(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
newRequest := api.ConstructRequest(params["id"])
requestChannel <- newRequest // <- 程序在这里停止,无法将值添加到通道中
w.Write([]byte("Received request"))
}
以上是你提供的代码。
英文:
Currently I am working on an application that can take anywhere from a few seconds to 1 hour + to process. Because of this using a channel to block requests while others are processing seems like a good fit. The following is an example of what Im trying to accomplish, however I am having an issue as it seems like my program is stalling when trying to add data into said channel (see below).
package main
import (
"net/http"
"github.com/gorilla/mux"
)
type Request struct {
Id string
}
func ConstructRequest(id string) Request {
return Request{Id: id}
}
var requestChannel chan Request // <- Create var for channel
func init() {
r := mux.NewRouter()
r.HandleFunc("/request/{id:[0-9]+}", ProcessRequest).Methods("GET")
http.Handle("/", r)
}
func main() {
// start server
http.ListenAndServe(":4000", nil)
requestChannel = make(chan Request) // <- Make channel and assign to var
go func() {
for {
request, ok := <-requestChannel
if !ok{
return
}
fmt.Println(request.Id)
}
}()
}
func ProcessRequest(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
newRequest := api.ConstructRequest(params["id"])
requestChannel <- newRequest // <- it is stopping here, not adding the value to the channel
w.Write([]byte("Received request"))
}
答案1
得分: 10
你的通道没有初始化,根据规范,在空通道上发送数据会导致阻塞。这是因为http.ListenAndServe
是一个阻塞操作,所以既没有调用requestChannel = make(chan Request)
,也没有调用你的go func()
。
将http.ListenAndServe
移到main
块的末尾应该可以解决这个问题。
英文:
Your channel is not initialised and, per specification, send on a nil channel blocks forever. This is because http.ListenAndServe
is a blocking operation, so neither requestChannel = make(chan Request)
nor your go func()
is being called.
Moving http.ListenAndServe
to the end of the main
block should fix the problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论