Golang,在处理HTTP请求时,无法将值推送到“全局”通道中。

huangapple go评论119阅读模式
英文:

Golang, unable to have value pushed into 'global' channel when handling HTTP requests

问题

目前我正在开发一个应用程序,处理时间可能从几秒钟到1小时以上不等。因此,在其他请求正在处理时使用通道来阻塞请求似乎是一个不错的选择。以下是我尝试实现的示例,但是我遇到了一个问题,似乎当尝试将数据添加到通道时,我的程序会停止响应(请参见下面的代码)。

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gorilla/mux"
  5. )
  6. type Request struct {
  7. Id string
  8. }
  9. func ConstructRequest(id string) Request {
  10. return Request{Id: id}
  11. }
  12. var requestChannel chan Request // <- 创建通道的变量
  13. func init() {
  14. r := mux.NewRouter()
  15. r.HandleFunc("/request/{id:[0-9]+}", ProcessRequest).Methods("GET")
  16. http.Handle("/", r)
  17. }
  18. func main() {
  19. // 启动服务器
  20. http.ListenAndServe(":4000", nil)
  21. requestChannel = make(chan Request) // <- 创建通道并赋值给变量
  22. go func() {
  23. for {
  24. request, ok := <-requestChannel
  25. if !ok {
  26. return
  27. }
  28. fmt.Println(request.Id)
  29. }
  30. }()
  31. }
  32. func ProcessRequest(w http.ResponseWriter, r *http.Request) {
  33. params := mux.Vars(r)
  34. newRequest := api.ConstructRequest(params["id"])
  35. requestChannel <- newRequest // <- 程序在这里停止,无法将值添加到通道中
  36. w.Write([]byte("Received request"))
  37. }

以上是你提供的代码。

英文:

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).

  1. package main
  2. import (
  3. &quot;net/http&quot;
  4. &quot;github.com/gorilla/mux&quot;
  5. )
  6. type Request struct {
  7. Id string
  8. }
  9. func ConstructRequest(id string) Request {
  10. return Request{Id: id}
  11. }
  12. var requestChannel chan Request // &lt;- Create var for channel
  13. func init() {
  14. r := mux.NewRouter()
  15. r.HandleFunc(&quot;/request/{id:[0-9]+}&quot;, ProcessRequest).Methods(&quot;GET&quot;)
  16. http.Handle(&quot;/&quot;, r)
  17. }
  18. func main() {
  19. // start server
  20. http.ListenAndServe(&quot;:4000&quot;, nil)
  21. requestChannel = make(chan Request) // &lt;- Make channel and assign to var
  22. go func() {
  23. for {
  24. request, ok := &lt;-requestChannel
  25. if !ok{
  26. return
  27. }
  28. fmt.Println(request.Id)
  29. }
  30. }()
  31. }
  32. func ProcessRequest(w http.ResponseWriter, r *http.Request) {
  33. params := mux.Vars(r)
  34. newRequest := api.ConstructRequest(params[&quot;id&quot;])
  35. requestChannel &lt;- newRequest // &lt;- it is stopping here, not adding the value to the channel
  36. w.Write([]byte(&quot;Received request&quot;))
  37. }

答案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.

huangapple
  • 本文由 发表于 2015年4月15日 05:55:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/29638068.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定