Add file cache implementation
This commit is contained in:
parent
611b508425
commit
df01f2eed7
|
@ -0,0 +1,30 @@
|
|||
package filecache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Load will look for a given file. If it exists, it would unmarshal its
|
||||
// contents into the given value. If the file does not exist, a supplied
|
||||
// function would be called and its output would be written to a file.
|
||||
func Load(val interface{}, filename string, fn func() interface{}) error {
|
||||
_, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
out := fn()
|
||||
reflect.ValueOf(val).Elem().Set(reflect.ValueOf(out))
|
||||
|
||||
body, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(filename, body, 0766)
|
||||
}
|
||||
body, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(body, val)
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package filecache
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileCache(t *testing.T) {
|
||||
filename := getTempFileName(t)
|
||||
const exp = 100
|
||||
var res int
|
||||
var nCalled int
|
||||
for i := 0; i < 10; i++ {
|
||||
err := Load(&res, filename, func() interface{} {
|
||||
nCalled++
|
||||
return exp
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error occurred while loading cache: %v", err)
|
||||
}
|
||||
|
||||
if res != exp {
|
||||
t.Errorf("Expected %d, got %d", exp, res)
|
||||
}
|
||||
}
|
||||
if nCalled != 1 {
|
||||
t.Errorf("Epected a function to be called once, was called %d times", nCalled)
|
||||
}
|
||||
}
|
||||
|
||||
func getTempFileName(t *testing.T) string {
|
||||
t.Helper()
|
||||
fd, err := ioutil.TempFile("", "filecache")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create a temporary file: %v", err)
|
||||
}
|
||||
if err := fd.Close(); err != nil {
|
||||
t.Fatalf("Failed to close temporary file: %v", err)
|
||||
}
|
||||
if err := os.Remove(fd.Name()); err != nil {
|
||||
t.Fatalf("Failed to delete temporary file: %v", err)
|
||||
}
|
||||
return fd.Name()
|
||||
}
|
Loading…
Reference in New Issue