public
Last active

Long polling with golang... only 282 clients?

  • Download Gist
Makefile
Makefile
1 2 3 4 5 6
include $(GOROOT)/src/Make.inc
 
TARG=long_polling
GOFILES=long_polling.go
 
include $(GOROOT)/src/Make.cmd
log
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
% 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
long_polling.go
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
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)
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.