Created
September 21, 2014 12:25
-
-
Save yoppi/3a2aafae5f8a9716f43d to your computer and use it in GitHub Desktop.
Webサイトを定期的にポーリングするやつ
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 ( | |
"log" | |
"net/http" | |
"time" | |
) | |
const ( | |
numPollers = 2 | |
statusInterval = 10 * time.Second | |
pollInterval = 60 * time.Second | |
errTimeout = 10 * time.Second | |
) | |
var urls = []string{ | |
"http://www.google.com/", | |
"http://golang.org/", | |
"http://blog.golang.org/", | |
} | |
type State struct { | |
url string | |
status string | |
} | |
func StateMonitor(interval time.Duration) chan<- State { | |
updates := make(chan State) | |
urlStatus := make(map[string]string) | |
ticker := time.NewTicker(interval) | |
go func() { | |
for { | |
select { | |
case <-ticker.C: | |
logState(urlStatus) | |
case s := <-updates: | |
urlStatus[s.url] = s.status | |
} | |
} | |
}() | |
return updates | |
} | |
func logState(s map[string]string) { | |
log.Println("Current state:") | |
for k, v := range s { | |
log.Printf("\t%s %s", k, v) | |
} | |
} | |
type Resource struct { | |
url string | |
errCount int | |
} | |
func (r *Resource) Poll() string { | |
resp, err := http.Head(r.url) | |
if err != nil { | |
log.Println("Error", r.url, err) | |
r.errCount++ | |
return err.Error() | |
} | |
r.errCount = 0 | |
return resp.Status | |
} | |
func (r *Resource) Sleep(done chan<- *Resource) { | |
time.Sleep(pollInterval + errTimeout*time.Duration(r.errCount)) | |
done <- r | |
} | |
func Poller(in <-chan *Resource, out chan<- *Resource, status chan<- State) { | |
for r := range in { | |
s := r.Poll() | |
status <- State{r.url, s} | |
out <- r | |
} | |
} | |
func main() { | |
pending := make(chan *Resource) | |
complete := make(chan *Resource) | |
status := StateMonitor(statusInterval) | |
for i := 0; i < numPollers; i++ { | |
go Poller(pending, complete, status) | |
} | |
go func() { | |
for _, url := range urls { | |
pending <- &Resource{url: url} | |
} | |
}() | |
for r := range complete { | |
go r.Sleep(pending) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment