Skip to content

Commit

Permalink
feat: add in-memory storage backend
Browse files Browse the repository at this point in the history
it can't be used in the cli yet
also means other backends need to be modified slightly
  • Loading branch information
Chloe Kudryavtsev committed Dec 17, 2019
1 parent 0fa593a commit 935f19b
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 1 deletion.
47 changes: 47 additions & 0 deletions storage/memory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package storage

var _ CHR = &Memory{}

// Memory is an in-memory non-persistent storage type
// using it in production is not recommended
type Memory struct {
store map[string]string
}

// Create will store a value in a key in memory
func (r *Memory) Create(key, value string, checkcollision bool) error {
if !r.Healthy() {
return Unhealthy
}
if checkcollision {
if _, ok := r.store[key]; ok {
return Collision
}
}
r.store[key] = value
return nil
}

// Read will read a key from memory, if it's there
func (r *Memory) Read(key string) (string, error) {
if !r.Healthy() {
return "", Unhealthy
}
if val, ok := r.store[key]; ok {
return val, nil
}
return "", Error("value not found")
}

// Healthy checks if the memory storage is initialized
func (r *Memory) Healthy() bool {
return r.store != nil
}

// NewMemory initializes a memory backend for use
func NewMemory() CHR {
m := Memory{
store: make(map[string]string),
}
return &m
}
56 changes: 56 additions & 0 deletions storage/memory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package storage

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMemory(t *testing.T) {
assert := assert.New(t)
const (
k = "key"
v1 = "val1"
v2 = "val2"
)

m := NewMemory()

err := m.Create(k, v1, false)
assert.Nil(err)

err = m.Create(k, v2, false)
assert.Nil(err)

err = m.Create(k, v1, true)
assert.Equal(Collision, err)

v, err := m.Read(k)
assert.Nil(err)
assert.Equal(v2, v)

_, err = m.Read(v1)
assert.NotNil(err)
assert.Equal(NotFound, err)
}

func TestUnhealthyMemory(t *testing.T) {
assert := assert.New(t)
m := &Memory{}

var (
e1 = m.Create("", "", false)
e2 = m.Create("", "", true)
_, e3 = m.Read("")
)

assert.NotNil(e1)
assert.NotNil(e2)
assert.NotNil(e3)

assert.Equal(Unhealthy, e1)
assert.Equal(Unhealthy, e2)
assert.Equal(Unhealthy, e3)

assert.False(m.Healthy())
}
2 changes: 1 addition & 1 deletion storage/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (r *Redis) Read(key string) (string, error) {
if !r.Healthy() {
return "", Unhealthy
}
return r.Get(key).Result()
return r.Get(key).Result() // TODO: return NotFound conditionally
}

// Healthy determines whether redis is responding to pings
Expand Down
2 changes: 2 additions & 0 deletions storage/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package storage
const (
// Collision is a fatal collision error, only triggered when it fails
Collision = Error("collision detected")
// NotFound is a fatal error when the backend cannot find a key to read
NotFound = Error("value not found")
// Unhealthy is a fatal error when the backend ceases to be healthy
Unhealthy = Error("backend unhealthy")
)
Expand Down

0 comments on commit 935f19b

Please sign in to comment.