Trouble responding to multiple requests at the same time
I am trying to convert my node.js HTTP server to Go. Here's what I want to happen:
I have a resource that gets generated intermittently (say every second or so), and I want all requests for this resource to wait until the next time it is generated. This way clients can poll and be guaranteed to get only the up-to-date resource. I am using web.go to remove a lot of the complexity of running an HTTP server.
Here is a brief version of my code:
package main
import (
"time"
"web"
"fmt"
vector "container/vector"
)
var listen开发者_开发技巧ers vector.Vector;
func resource (ctx *web.Context) {
c := make(chan int)
listeners.Push(c)
go func() {
<-c
go func() {
ctx.WriteString("Cool")
fmt.Println("Wrote something")
}()
}()
}
func resourceLoop() {
time.Sleep(5 * 1000 * 1000000) // sleep for 5 seconds
for ; listeners.Len() > 0 ; {
c := listeners.Pop().(chan int)
c <- 1
}
go resourceLoop()
}
func main() {
web.Get("/resource", resource)
go resourceLoop()
web.Run("localhost:4000")
}
I would expect there to be a Context.End() or similar function, but it doesn't seem to have one. I read the source for web.go, but I couldn't figure out where it was ending the response (web.go:268 is where my resource() is called). In node.js this is trivial, you can call a ServerResponse.end().
When I kill the server while running the script in Chrome, I get this output (seems to be correct, except that the response isn't ending):
4
Cool
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Date: Sat, 16 Apr 2011 00:37:58 GMT
Server: web.go
Transfer-Encoding: chunked
0
Is this a problem with the web.go framework or am I doing something wrong? If it's a problem with the framework, I'll file an issue with him.
I'm pretty new to Go, so I could be going about this completely wrong.
I've never used web.go, but it seems that your example is entirely too complicated. Why do you need a goroutine to spawn a goroutine? I would assume the framework itself would take care of concurrency and just write this:
func resource (ctx *web.Context, val string) string {
c := make(chan int)
listeners.Push(c)
<-c
return "Cool"
}
Otherwise, it looks like it is doing exactly what you want and you just need to close the connection if you're truly done with it:
ctx.Close()
精彩评论