Skip to content

Instantly share code, notes, and snippets.

@tomnomnom
Created May 28, 2016 22:42
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 tomnomnom/0ef06cd9221161499bae9ffd28383f7f to your computer and use it in GitHub Desktop.
Save tomnomnom/0ef06cd9221161499bae9ffd28383f7f to your computer and use it in GitHub Desktop.
Using Go's channels to spread work across a bunch of worker goroutines
package main
import (
"fmt"
"net"
"sync"
"time"
)
const (
// numWorkers is the number of worker goroutines to use
numWorkers = 10
// connectTimeout is the time to wait before considering a port closed
connectTimeout = time.Millisecond * 500
)
// A job contains the host:port to connect to and the result
// of that connection attempt
type job struct {
host string
res bool
}
// worker waits for jobs on an input channel, tries to connect to
// the job host:port, adds the result to the job and sends it on
// the provided output channel
func worker(in chan job, out chan job) {
for {
j, ok := <-in
if !ok {
return
}
conn, err := net.DialTimeout("tcp", j.host, connectTimeout)
if err == nil {
j.res = true
_ = conn.Close()
}
out <- j
}
}
func main() {
// Use a WaitGroup to make sure we get the result from
// every job in the queue
var wg sync.WaitGroup
// Prep a job queue
var jobs []job
for i := 1; i <= 65535; i++ {
wg.Add(1)
jobs = append(jobs, job{fmt.Sprintf("192.168.1.23:%d", i), false})
}
// Spin up some workers
in := make(chan job)
out := make(chan job)
for i := 0; i < numWorkers; i++ {
go worker(in, out)
}
// We need to start handling job results before we add
// any to the queue otherwise it will deadlock
go func() {
for {
r, ok := <-out
if !ok {
return
}
if r.res {
fmt.Printf("%s is open\n", r.host)
}
wg.Done()
}
}()
// Feed the jobs into the queue
for _, j := range jobs {
in <- j
}
// Wait for everything to finish and then close the
// input and output channels
wg.Wait()
close(in)
close(out)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment