diff --git a/README.md b/README.md index eabbb6c..d01eab2 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,16 @@ func main() { // creating the new resource r := updatingresource.NewUpdatingResource("-", f, 500 * time.Millisecond) - // query the resource 6 times - for i := 0; i <6; i++{ + // query the resource 8 times + for i := 0; i <8; i++{ time.Sleep(200 * time.Millisecond) x := r.Get().(string) fmt.Printf("%s\n", x) + + // stop updating after the 6th time + if i == 6 { + r.Done() + } } } ~~~~ \ No newline at end of file diff --git a/example_basic_test.go b/example_basic_test.go index 4da84fa..7dfd278 100644 --- a/example_basic_test.go +++ b/example_basic_test.go @@ -17,11 +17,16 @@ func Example() { // creating the new resource r := updatingresource.NewUpdatingResource("-", f, 500 * time.Millisecond) - // query the resource 6 times - for i := 0; i <6; i++{ + // query the resource 8 times + for i := 0; i <8; i++{ time.Sleep(200 * time.Millisecond) x := r.Get().(string) fmt.Printf("%s\n", x) + + // stop updating after the 6th time + if i == 6 { + r.Done() + } } // Output: @@ -31,4 +36,6 @@ func Example() { // -- // --- // --- + // --- + // --- } diff --git a/updatingresource.go b/updatingresource.go index 0be2542..a73b8cf 100644 --- a/updatingresource.go +++ b/updatingresource.go @@ -10,30 +10,41 @@ import ( type UpdatingResource struct { mu *sync.RWMutex x *interface{} + done chan bool } // NewUpdatingResource creates a new UpdatingResource. Thereby, f is the function // that will be called every ttl to compute a new value for x (i.e. x=f(x)). func NewUpdatingResource(x interface{}, f func(x interface{}) interface{}, ttl time.Duration) *UpdatingResource { var mu sync.RWMutex + done := make(chan bool) go func(f func(x interface{}) interface{}) { ticker := time.NewTicker(ttl) for { - <-ticker.C - y := f(x) - mu.Lock() - x = y - mu.Unlock() + select { + case <-done: + return + case <-ticker.C: + y := f(x) + mu.Lock() + x = y + mu.Unlock() + } } }(f) - resource := UpdatingResource{x: &x, mu: &mu} + resource := UpdatingResource{x: &x, mu: &mu, done: done} return &resource } -// Get returns the current value of the encapsulated object. Get is thread-safe +// Get returns the current value of the wrapped object. Get is thread-safe // wrt. to the function updating the encapsulated object. func (r *UpdatingResource) Get() interface{} { r.mu.RLock() defer r.mu.RUnlock() return *r.x } + +// Done stops the updating of the wrapped object. +func (r *UpdatingResource) Done() { + r.done <- true +} \ No newline at end of file