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

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

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 (
    &quot;net/http&quot;

    &quot;github.com/gorilla/mux&quot;
)

type Request struct {
    Id string
}

func ConstructRequest(id string) Request {
    return Request{Id: id}
}

var requestChannel chan Request // &lt;- Create var for channel

func init() {
    r := mux.NewRouter()
    r.HandleFunc(&quot;/request/{id:[0-9]+}&quot;, ProcessRequest).Methods(&quot;GET&quot;)
    http.Handle(&quot;/&quot;, r)
}

func main() {
    // start server
	http.ListenAndServe(&quot;:4000&quot;, nil)

    requestChannel = make(chan Request) // &lt;- Make channel and assign to var

    go func() {
	    for {
		    request, ok := &lt;-requestChannel
		
			if !ok{
    			return
	    	}
		
		    fmt.Println(request.Id)
	    }
	}()

}

func ProcessRequest(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)

	newRequest := api.ConstructRequest(params[&quot;id&quot;])

    requestChannel &lt;- newRequest // &lt;- it is stopping here, not adding the value to the channel

	w.Write([]byte(&quot;Received request&quot;))
}

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

确定