Skip to content

Instantly share code, notes, and snippets.

@timbogit
Created August 8, 2013 06:10
Show Gist options
  • Save timbogit/6181890 to your computer and use it in GitHub Desktop.
Save timbogit/6181890 to your computer and use it in GitHub Desktop.
for-select loop for a feed reader as presented in "Advanced Go Concurrency Patterns" (Sameer Ajmani, Google I/O 2013)
func (s *sub) loop() {
var pending []Item // appended by fetch; consumed by send
var next time.Time // initially January 1, year 0
var err error // set when Fetch fails
for {
var first Item
var updates chan Item
if len(pending) > 0 {
first = pending[0]
updates = s.updates // enable send case
}
var fetchDelay time.Duration // initally 0 (no delay)
if now := time.Now(); next.After(now) {
fetchDelay = next.Sub(now)
}
startFetch := time.After(fetchDelay)
select {
case errc := <-s.closing:
errc <- err
close(s.updates)
return
case <-startFetch:
var fetched []Item
fetched, next, err = s.fetcher.Fetch()
if err != nil {
next = time.Now().Add(10 * time.Second)
break
}
pending = append(pending, fetched...)
case updates <- first:
pending = pending[1:]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment