Created
February 27, 2017 01:06
-
-
Save bdarnell/2d37a812368bb83090ab60d36ceae3c4 to your computer and use it in GitHub Desktop.
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 ( | |
"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