Skip to content

Instantly share code, notes, and snippets.

@radeksimko
Created July 25, 2015 18:42
Show Gist options
  • Save radeksimko/faa1371e494bd8d07147 to your computer and use it in GitHub Desktop.
Save radeksimko/faa1371e494bd8d07147 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net/http"
"os"
"sync"
"time"
)
// Based on ulimit to prevent "too many open files"
const NumberOfTokens = 2000
const HttpTimeout = time.Second * 10
func main() {
url := os.Args[1]
ch := make(chan string)
var wg sync.WaitGroup
poolCh := make(chan bool, NumberOfTokens)
for i := 0; i < NumberOfTokens; i++ {
poolCh <- true
}
defer close(ch)
defer close(poolCh)
wg.Add(1) // One extra to block
go func() {
i := 0
for {
i += 1
wg.Add(1)
go callUrl(i, url, ch, &wg, poolCh)
}
}()
go func() {
for message := range ch {
fmt.Println(message)
}
}()
wg.Wait()
}
func callUrl(i int, url string, ch chan string, wg *sync.WaitGroup, sem chan bool) {
defer wg.Done()
// Wait until we get a token
<-sem
defer func() {
// Put token back to pool
sem <- true
}()
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
ResponseHeaderTimeout: HttpTimeout,
}
client := &http.Client{Transport: transport}
resp, err := client.Get(url)
if err != nil {
ch <- fmt.Sprintf("%d: Error: %s", i, err.Error())
return
}
ch <- fmt.Sprintf("%d: Success: %s", i, resp.Status)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment