Go Channel读写陷入无限循环
First of all, I want to make Long Polling notification system. To be more specific, I will make http request, and response will be returned only if map channel is true
.
This is the code block I used:
var MessageNotification = make(map[string]chan bool, 10)
func GetNotification(id int, timestamp int) notification {
<-MessageNotification["1"]
var chat_services []*models.Chat_service
o := orm.NewOrm()
_, err := o.QueryTable("chat_service").Filter("Sender__id", id).RelatedSel().All(&chat_services)
if err != nil {
return notification{Status: false}
}
return notification{Status: true, MessageList: chat_services}
}
func SetNotification(id int) {
MessageNotification[strconv.Itoa(id)] <- true
}
This is controller block :
func (c *ChatController) Notification() {
data := chat.GetNotification(1,0)
c.Data["json"] = data
c.ServeJSON()
}
func (c *ChatController) Websocket(){
chat.SetNotification(1)
c.Data["json"] = "test"
c.ServeJSON();
}
function names and variable created for test.
No error occurred. Thanks for your help.
You're not creating your channel.
var MessageNotification = make(map[string]chan bool, 10)
This line makes a map with capacity 10, but you're not creating the actual channels in the map. As a result, `SetNotification["1"] is a nil channel, and sends and receives on nil channels block indefinitely.
You need to put in
MessageNotification["1"] = make(chan bool)
You can include a size if desired (and I have a hunch your "10" in the map make was supposed to be the buffering for that channel). This can even be done conditionally:
func GetNotification(id int, timestamp int) notification {
if _, ok := MessageNotification["1"]; !ok { // if map does not contain that key
MessageNotification["1"] = make(chan bool, 10)
}
<-MessageNotification["1"]
// ...
}
func SetNotification(id int) {
if _, ok := MessageNotification[strconv.Itoa(id)]; !ok { // if map does not contain that key
MessageNotification[strconv.Itoa(id)] = make(chan bool, 10)
}
MessageNotification[strconv.Itoa(id)] <- true
}
This way the first location that tries to access the channel adds it to the map and properly makes the channel, so sends and receives on it will actually function.