Skip to content

Instantly share code, notes, and snippets.

@bdarnell
Created February 27, 2017 01:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdarnell/2d37a812368bb83090ab60d36ceae3c4 to your computer and use it in GitHub Desktop.
Save bdarnell/2d37a812368bb83090ab60d36ceae3c4 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"math/rand"
"net"
"sync"
"time"
)
func main() {
const num = 100000
var wg sync.WaitGroup
wg.Add(num * 2)
var duration time.Duration
sem := make(chan struct{}, 5)
for i := 0; i < num; i++ {
sem <- struct{}{}
ctx, cancel := context.WithCancel(context.Background())
go func() {
// Sleep a bit before canceling the context. The goal is to race
// the cancellation against the "connection refused" packet from
// the remote host, so adjust the constant below based on ping
// time.
time.Sleep(time.Duration(rand.Int63n(int64(5 * time.Millisecond))))
cancel()
wg.Done()
}()
go func(i int) {
start := time.Now()
// Attempt to connect to a port where nothing is listening. This
// should be a responsive host to ensure that it fails with
// ECONNREFUSED instead of a timeout. It must not be localhost,
// because we need connection attempts to not be instantaneous.
_, err := (&net.Dialer{}).DialContext(ctx, "tcp4", "192.168.1.1:1")
duration += time.Since(start)
if err == nil {
panic(fmt.Sprintf("Dial to unbound port succeeded on attempt %d", i))
}
wg.Done()
<-sem
}(i)
}
wg.Wait()
fmt.Printf("avg duration: %s\n", duration/num)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment