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