Skip to content

Instantly share code, notes, and snippets.

@okzk
Created August 19, 2016 03:04
Show Gist options
  • Save okzk/4e5afec27927668e52d5eb6c5eb1bb72 to your computer and use it in GitHub Desktop.
Save okzk/4e5afec27927668e52d5eb6c5eb1bb72 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
"sync"
)
type (
// Dispatcher represents a management workers.
Dispatcher struct {
queue chan interface{}
wg sync.WaitGroup
}
)
const (
maxWorkers = 3
maxQueues = 10000
)
// NewDispatcher returns a pointer of Dispatcher.
func NewDispatcher() *Dispatcher {
d := &Dispatcher{
queue: make(chan interface{}, maxQueues),
}
return d
}
// Add adds a given value to the queue of the dispatcher.
func (d *Dispatcher) Add(v interface{}) {
d.queue <- v
}
// ワーカー立ち上げるよ
func (d *Dispatcher) Start() {
d.wg.Add(maxWorkers)
for i := 0; i < maxWorkers; i++ {
go func() {
defer d.wg.Done()
for v := range d.queue {
if str, ok := v.(string); ok {
get(str)
}
}
}()
}
}
// 元コードは引数で分岐してたけど、混乱しないようにメソッド分けたよ!
func (d *Dispatcher) Stop() {
close(d.queue)
d.wg.Wait()
}
func (d *Dispatcher) StopImmediately() {
close(d.queue)
// (それが良いのかはアレだけど)溜まってるキューを全部読み捨てるよ!
for range d.queue {
}
d.wg.Wait()
}
func get(url string) {
resp, err := http.DefaultClient.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Printf("Goroutine:%d, URL:%s (%d bytes)", runtime.NumGoroutine(), url, len(body))
}
func main() {
d := NewDispatcher()
d.Start()
for i := 0; i < 100; i++ {
url := fmt.Sprintf("http://placehold.it/%dx%d", i, i)
d.Add(url)
}
d.Stop()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment