add notification function to store module and add unit-test

This commit is contained in:
Xiang Li 2013-06-07 14:57:00 -07:00
parent f8ca35fd77
commit e9ac8b1b98
4 changed files with 41 additions and 15 deletions

View File

@ -6,10 +6,25 @@ import (
"encoding/json" "encoding/json"
) )
// CONSTANTS
const (
ERROR = -(1 + iota)
SET
DELETE
)
type Store struct { type Store struct {
Nodes map[string]string `json:"nodes"` Nodes map[string]string `json:"nodes"`
} }
// global store
var s *Store
func init() {
s = createStore()
}
// make a new stroe
func createStore() *Store{ func createStore() *Store{
s := new(Store) s := new(Store)
s.Nodes = make(map[string]string) s.Nodes = make(map[string]string)
@ -25,14 +40,14 @@ func (s *Store) Set(key string, value string) (string, bool) {
if ok { if ok {
s.Nodes[key] = value s.Nodes[key] = value
w.notify(SET, key, oldValue, value)
return oldValue, true return oldValue, true
} else { } else {
s.Nodes[key] = value s.Nodes[key] = value
w.notify(SET, key, "", value)
return "", false return "", false
} }
} }
// get the value of the key // get the value of the key
@ -56,6 +71,9 @@ func (s *Store) Delete(key string) (string, error) {
if ok { if ok {
delete(s.Nodes, key) delete(s.Nodes, key)
w.notify(DELETE, key, oldValue, "")
return oldValue, nil return oldValue, nil
} else { } else {
return "", errors.New("Key does not exist") return "", errors.New("Key does not exist")

View File

@ -5,18 +5,17 @@ import (
) )
func TestStoreGet(t *testing.T) { func TestStoreGet(t *testing.T) {
store := createStore()
store.Set("foo", "bar") s.Set("foo", "bar")
value, err := store.Get("foo") value, err := s.Get("foo")
if err!= nil || value != "bar" { if err!= nil || value != "bar" {
t.Fatalf("Cannot get stored value") t.Fatalf("Cannot get stored value")
} }
store.Delete("foo") s.Delete("foo")
value, err = store.Get("foo") value, err = s.Get("foo")
if err == nil{ if err == nil{
t.Fatalf("Got deleted value") t.Fatalf("Got deleted value")
@ -24,11 +23,10 @@ func TestStoreGet(t *testing.T) {
} }
func TestSaveAndRecovery(t *testing.T) { func TestSaveAndRecovery(t *testing.T) {
store := createStore()
store.Set("foo", "bar") s.Set("foo", "bar")
state, err := store.Save() state, err := s.Save()
if err != nil { if err != nil {
t.Fatalf("Cannot Save") t.Fatalf("Cannot Save")

View File

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
) )
// CONSTANTS
type Watcher struct { type Watcher struct {
chanMap map[string][]chan Notification chanMap map[string][]chan Notification
@ -19,12 +18,22 @@ type Notification struct {
newValue string newValue string
} }
// global watcher
var w *Watcher
// init the global watcher
func init() {
w = createWatcher()
}
// create a new watcher
func createWatcher() *Watcher { func createWatcher() *Watcher {
w := new(Watcher) w := new(Watcher)
w.chanMap = make(map[string][]chan Notification) w.chanMap = make(map[string][]chan Notification)
return w return w
} }
// register a function with channel and prefix to the watcher
func (w *Watcher) add(prefix string, c chan Notification, f func(chan Notification)) error { func (w *Watcher) add(prefix string, c chan Notification, f func(chan Notification)) error {
prefix = path.Clean(prefix) prefix = path.Clean(prefix)
@ -44,6 +53,7 @@ func (w *Watcher) add(prefix string, c chan Notification, f func(chan Notificati
return nil return nil
} }
// notify the watcher a action happened
func (w *Watcher) notify(action int, key string, oldValue string, newValue string) error { func (w *Watcher) notify(action int, key string, oldValue string, newValue string) error {
key = path.Clean(key) key = path.Clean(key)

View File

@ -6,12 +6,12 @@ import (
) )
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
watcher := createWatcher() // watcher := createWatcher()
c := make(chan Notification) c := make(chan Notification)
d := make(chan Notification) d := make(chan Notification)
watcher.add("/", c, say) w.add("/", c, say)
watcher.add("/prefix/", d, say) w.add("/prefix/", d, say)
watcher.notify(0, "/prefix/hihihi", "1", "1") s.Set("/prefix/foo", "bar")
} }
func say(c chan Notification) { func say(c chan Notification) {