Skip to content

Instantly share code, notes, and snippets.

@jbarber
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbarber/29f23104b745eb33e500 to your computer and use it in GitHub Desktop.
Save jbarber/29f23104b745eb33e500 to your computer and use it in GitHub Desktop.
Function that returns updated values once every time period, no matter how often it is called
package main
import (
"fmt"
"time"
)
// This function returns a function that returns the current time. The current
// time is only updated when the returned function is called, and at most once
// during every period
func updater(period time.Duration, value func() interface{}) func() interface{} {
v := value()
wanted := make(chan bool)
// Anonymous function that returns a function that returns a timer of the
// duration requested (period). So every application of newtimer()
// gets an alarm that will go off in 5 seconds
newtimer := func(next time.Duration) func() <-chan time.Time {
return func() <-chan time.Time {
return time.After(next)
}
}(period)
// Closure that returns the current value of v
getvalue := func() interface{} {
wanted <- true
return v
}
// Go routine that updates the value of v when the timer expires (refresh is
// set to true) and a request to know the value is made through the closure
// ret (a message is sent through the channel c)
go func() {
refresh := false
timer := newtimer()
for {
select {
case <-timer:
refresh = true
timer = newtimer()
case <-wanted:
if refresh {
v = value()
refresh = false
timer = newtimer()
}
}
}
}()
return getvalue
}
func main() {
v := updater(5*time.Second, func() interface{} { return time.Now() })
for {
time.Sleep(1 * time.Second)
fmt.Println(v())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment