Skip to content

Commit

Permalink
Add cache examples
Browse files Browse the repository at this point in the history
  • Loading branch information
deanishe committed Feb 13, 2018
1 parent 26de564 commit 0d24b02
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 2 deletions.
3 changes: 1 addition & 2 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ type Cache struct {
}

// NewCache creates a new Cache using given directory.
// Directory dir is created if it doesn't exist. The function will panic
// if directory can't be created.
// Directory is created if it doesn't exist. Panics if directory can't be created.
func NewCache(dir string) *Cache {
util.MustExist(dir)
return &Cache{dir}
Expand Down
198 changes: 198 additions & 0 deletions cache_examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//
// Copyright (c) 2018 Dean Jackson <[email protected]>
//
// MIT Licence. See http://opensource.org/licenses/MIT
//
// Created on 2018-02-13
//

package aw

import (
"fmt"
"io/ioutil"
"os"
"time"
)

func ExampleCache() {

var (
// Cache "key" (filename) and the value to store
name = "LastOpened"
value = time.Now()
)

// Create a temporary directory for Cache to use
dir, err := ioutil.TempDir("", "awgo-demo")
if err != nil {
panic(err)
}
defer os.RemoveAll(dir)

// Create a new cache
c := NewCache(dir)

// Cache doesn't exist yet
fmt.Println(c.Exists(name))

// The API uses bytes
data, _ := value.MarshalText()

if err := c.Store(name, data); err != nil {
panic(err)
}

// Cache now exists
fmt.Println(c.Exists(name))

// Load data from cache
data, err = c.Load(name)
if err != nil {
panic(err)
}

v2 := time.Time{}
v2.UnmarshalText(data)

// Values are equal
fmt.Println(value.Equal(v2))

// Output:
// false
// true
// true
}

// LoadOrStore loads data from cache if they're fresh enough, otherwise it calls
// the reload function for new data (which it caches).
func ExampleCache_LoadOrStore() {

var (
name = "Expiring"
data = []byte("test")
maxAge = time.Millisecond * 1000
start = time.Now()
reloadCount int
)

// Create a temporary directory for Cache to use
dir, err := ioutil.TempDir("", "awgo-demo")
if err != nil {
panic(err)
}
defer os.RemoveAll(dir)

// Create a new cache
c := NewCache(dir)

// Called by LoadOrStore when cache is empty or has expired
reload := func() ([]byte, error) {

// Log call count
reloadCount++
fmt.Printf("reload #%d\n", reloadCount)

return data, nil
}

// Cache is empty
fmt.Println(c.Exists(name))

out, err := c.LoadOrStore(name, maxAge, reload)
if err != nil {
panic(err)
}

// Reload was called and cache exists
fmt.Println(c.Exists(name))

// Value is the same
fmt.Println(string(out) == string(data))

// Load again, this time from cache, not reload
out, err = c.LoadOrStore(name, maxAge, reload)
if err != nil {
panic(err)
}

// Value is the same
fmt.Println(string(out) == string(data))

// Wait for cache to expire, then try again
time.Sleep(maxAge - time.Now().Sub(start))

// reload is called again
out, err = c.LoadOrStore(name, maxAge, reload)
if err != nil {
panic(err)
}

// Value is the same
fmt.Println(string(out) == string(data))

// Output:
// false
// reload #1
// true
// true
// true
// reload #2
// true
}

// LoadOrStoreJSON marshals JSON to/from the cache.
func ExampleCache_LoadOrStoreJSON() {

var (
name = "Host"
maxAge = time.Second * 5
)

// Create a temporary directory for Cache to use
dir, err := ioutil.TempDir("", "awgo-demo")
if err != nil {
panic(err)
}
defer os.RemoveAll(dir)

// struct to cache
type host struct {
Hostname string
Port int
}

// Called by LoadOrStoreJSON. Returns default host.
// Normally, this function would do something that takes some time, like
// fetch data from the web or an application.
reload := func() (interface{}, error) {

fmt.Println("reload")

return &host{
Hostname: "localhost",
Port: 6000,
}, nil
}

// Create a new cache
c := NewCache(dir)

// Cache is empty
fmt.Println(c.Exists(name))

// Populate new host from cache/reload
h := &host{}
if err := c.LoadOrStoreJSON(name, maxAge, reload, h); err != nil {
panic(err)
}

fmt.Println(h.Hostname)
fmt.Println(h.Port)

// Output:
// false
// reload
// localhost
// 6000
}

0 comments on commit 0d24b02

Please sign in to comment.