Created
August 8, 2013 06:10
-
-
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)
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
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