From ae974083aa7bc79b44ee1f9440509e5ee9bcc6a6 Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Mon, 9 Apr 2018 20:30:52 -0700 Subject: [PATCH] just fetch periodically --- main.go | 64 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/main.go b/main.go index 946ce43..9dfe7a3 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "context" "flag" "fmt" "image" @@ -12,45 +13,55 @@ import ( "os" "sync" "time" + + "github.com/pkg/errors" ) var port = flag.Int("port", 8000, "port") +var freq = flag.Duration("d", 15*time.Second, "refresh interval") type Now struct { - lastUpdated time.Time - cacheWindow time.Duration - buffer *bytes.Buffer - lock sync.RWMutex + sync.RWMutex + + cache *bytes.Buffer } -func NewNow(d time.Duration) *Now { - return &Now{ - cacheWindow: d, - buffer: &bytes.Buffer{}, +func NewNow(ctx context.Context, d time.Duration) *Now { + n := &Now{ + cache: &bytes.Buffer{}, } + + n.Update() + go func() { + t := time.NewTicker(d) + for { + select { + case <-t.C: + n.Update() + case <-ctx.Done(): + return + } + } + }() + + return n } func (n *Now) ServeHTTP(w http.ResponseWriter, req *http.Request) { - log.Printf("%+v", req.RemoteAddr) - if time.Now().After(n.lastUpdated.Add(n.cacheWindow)) { - log.Println("updating image") - n.Update() - n.lastUpdated = time.Now() - } - n.lock.RLock() - w.Write(n.buffer.Bytes()) - n.lock.RUnlock() + n.RLock() + w.Write(n.cache.Bytes()) + n.RUnlock() } -func (n *Now) Update() { +func (n *Now) Update() error { resp, err := http.Get("http://imgs.xkcd.com/comics/now.png") if err != nil { - log.Fatal(err) + return errors.Wrap(err, "get") } defer resp.Body.Close() src, err := png.Decode(resp.Body) if err != nil { - log.Fatal(err) + return errors.Wrap(err, "png decode") } bounds := src.Bounds() dest := image.NewNRGBA(bounds) @@ -64,9 +75,12 @@ func (n *Now) Update() { } } } - n.lock.Lock() - png.Encode(n.buffer, dest) - n.lock.Unlock() + + n.Lock() + png.Encode(n.cache, dest) + n.Unlock() + + return nil } func main() { @@ -79,7 +93,9 @@ func main() { log.Printf("serving on: http://%s:%d/", hostname, *port) addr := fmt.Sprintf(":%d", *port) - http.Handle("/", NewNow(15*time.Minute)) + n := NewNow(context.Background(), *freq) + + http.Handle("/", n) err = http.ListenAndServe(addr, nil) if err != nil {