Created
June 22, 2011 09:48
-
-
Save nono/1039785 to your computer and use it in GitHub Desktop.
Long polling with golang... only 282 clients?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% 8g -V | |
8g version weekly.2011-06-16 8787+ | |
% make && ./long_polling | |
8g -o _go_.8 long_polling.go | |
8l -o long_polling _go_.8 | |
(On a second shell: % ab -c 1000 -n 1000 http://localhost:8000/) | |
New client: 1 | |
New client: 2 | |
New client: 3 | |
New client: 4 | |
[...] | |
New client: 281 | |
New client: 282 | |
% ps aux | |
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND | |
nono 23835 0.6 0.4 3119508 9008 pts/2 Sl+ 11:19 0:00 ./long_polling |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"container/vector" | |
"fmt" | |
"http" | |
"io" | |
"io/ioutil" | |
"log" | |
"os" | |
"os/signal" | |
"time" | |
) | |
func ChannelsKeeper(clients chan chan string, signals chan bool) { | |
channels := new(vector.Vector) | |
counter := 0 | |
go func() { | |
for { | |
select { | |
case <-signals: | |
msg := fmt.Sprintf("%d\n", counter) | |
for channels.Len() > 0 { | |
channel := channels.Pop().(chan string) | |
channel <- msg | |
close(channel) | |
} | |
counter++ | |
case c := <-clients: | |
channels.Push(c) | |
fmt.Printf("New client: %d\n", channels.Len()) | |
} | |
} | |
}() | |
} | |
func InstallSignalHandlers(signals chan bool) { | |
go func() { | |
for s := range signal.Incoming { | |
if s == os.SIGINT { | |
fmt.Printf("\nCtrl-C signalled\n") | |
os.Exit(0) | |
} else if s == os.SIGUSR1 { | |
signals <- true | |
} | |
} | |
}() | |
} | |
func CreatePidfile() { | |
pid := []byte(fmt.Sprintf("%d", os.Getpid())) | |
ioutil.WriteFile("long_polling.pid", pid, 0755) | |
} | |
func MakeLPHandler(clients chan chan string) func(w http.ResponseWriter, r *http.Request) { | |
return func(w http.ResponseWriter, r *http.Request) { | |
timeout := make(chan bool, 1) | |
message := make(chan string, 1) | |
clients <- message | |
go func () { | |
time.Sleep(60e9) | |
timeout <- true | |
close(timeout) | |
}() | |
select { | |
case <-timeout: | |
io.WriteString(w, "Timeout!\n") | |
case msg := <-message: | |
io.WriteString(w, msg) | |
} | |
} | |
} | |
func CreateHttpServer(clients chan chan string) { | |
http.HandleFunc("/", MakeLPHandler(clients)) | |
err := http.ListenAndServe(":8000", nil) | |
if err != nil { | |
log.Fatal("ListenAndServe: ", err.String()) | |
} | |
} | |
func main() { | |
clients := make(chan chan string, 1) | |
signals := make(chan bool, 1) | |
CreatePidfile() | |
ChannelsKeeper(clients, signals) | |
InstallSignalHandlers(signals) | |
CreateHttpServer(clients) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include $(GOROOT)/src/Make.inc | |
TARG=long_polling | |
GOFILES=long_polling.go | |
include $(GOROOT)/src/Make.cmd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment