Skip to content

Commit

Permalink
Merge pull request #6 from Alkorin/helpers
Browse files Browse the repository at this point in the history
Helpers
  • Loading branch information
Alkorin committed May 21, 2016
2 parents 46a265f + ef3fa71 commit 8f3f1b4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
40 changes: 40 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cache

import (
"time"
)

type timeOutResult struct {
r interface{}
e error
}

func WithTimeout(f cacheGetterFunc, t time.Duration, err error) cacheGetterFunc {
return func(v interface{}) (interface{}, error) {
c := make(chan timeOutResult)
go func() {
r, e := f(v)
c <- timeOutResult{r, e}
}()
select {
case r := <-c:
return r.r, r.e
case <-time.After(t):
}
return nil, err
}
}

func WithRetry(f cacheGetterFunc, n int) cacheGetterFunc {
return func(v interface{}) (interface{}, error) {
var lastError error
for i := 0; i < n; i++ {
r, e := f(v)
if e == nil {
return r, e
}
lastError = e
}
return nil, lastError
}
}
53 changes: 53 additions & 0 deletions helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cache

import (
"errors"
"testing"
"time"
)

func TestTimeout(t *testing.T) {
// Func which waits v and returns OK
f := func(v interface{}) (interface{}, error) {
time.Sleep(v.(time.Duration))
return "OK", nil
}

// Returns err if call is more than 100ms
f = WithTimeout(f, 100*time.Millisecond, errors.New("timed out"))

// Call with 50ms, should return 'OK'
if v, e := f(50 * time.Millisecond); v.(string) != "OK" || e != nil {
t.Fatalf("Should have returned OK, nil; received: %v, %v", v, e)
}

// Call with 200ms, should return 'timed out'
if v, e := f(200 * time.Millisecond); v != nil || e == nil || e.Error() != "timed out" {
t.Fatalf("Should have returned nil, 'timed out'; received: %v, %v", v, e)
}
}

func TestRetry(t *testing.T) {
nbCalled := 0
// Func which returns OK only at the second call
f := func(v interface{}) (interface{}, error) {
nbCalled++
if nbCalled == 2 {
return "OK", nil
}
return nil, errors.New("not second")
}

// Try to call func 3 times
f = WithRetry(f, 3)

// First try, should call the function 2 times and return success
if v, e := f(nil); nbCalled != 2 || v.(string) != "OK" || e != nil {
t.Fatalf("Should have returned 2, OK, nil; received: %v, %v, %v", nbCalled, v, e)
}

// Second try, should call the function 3 times and return error
if v, e := f(nil); nbCalled != 5 || v != nil || e == nil || e.Error() != "not second" {
t.Fatalf("Should have returned 5, nil, 'not second'; received: %v, %v, %v", nbCalled, v, e)
}
}

0 comments on commit 8f3f1b4

Please sign in to comment.