1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#Examples
This document contains useful example of usage for `libkv`. It might not be complete but provides with general informations on how to use the client.
##Create a store and use Put/Get/Delete
```go
package main
import (
"fmt"
"time"
"log"
"github.com/docker/libkv"
"github.com/docker/libkv/store"
"github.com/docker/libkv/store/consul"
)
func init() {
// Register consul store to libkv
consul.Register()
// We can register as many backends that are supported by libkv
etcd.Register()
zookeeper.Register()
boltdb.Register()
}
func main() {
client := "localhost:8500"
// Initialize a new store with consul
kv, err := libkv.NewStore(
store.CONSUL, // or "consul"
[]string{client},
&store.Config{
ConnectionTimeout: 10*time.Second,
},
)
if err != nil {
log.Fatal("Cannot create store consul")
}
key := "foo"
err = kv.Put(key, []byte("bar"), nil)
if err != nil {
fmt.Errorf("Error trying to put value at key: %v", key)
}
pair, err := kv.Get(key)
if err != nil {
fmt.Errorf("Error trying accessing value at key: %v", key)
}
err = kv.Delete(key)
if err != nil {
fmt.Errorf("Error trying to delete key %v", key)
}
log.Info("value: ", string(pair.Value))
}
```
##List keys
```go
// List will list all the keys under `key` if it contains a set of child keys/values
entries, err := kv.List(key)
for _, pair := range entries {
fmt.Printf("key=%v - value=%v", pair.Key, string(pair.Value))
}
```
##Watching for events on a single key (Watch)
You can use watches to watch modifications on a key. First you need to check if the key exists. If this is not the case, we need to create it using the `Put` function.
```go
// Checking on the key before watching
if !kv.Exists(key) {
err := kv.Put(key, []byte("bar"), nil)
if err != nil {
fmt.Errorf("Something went wrong when initializing key %v", key)
}
}
stopCh := make(<-chan struct{})
events, err := kv.Watch(key, stopCh)
select {
case pair := <-events:
// Do something with events
fmt.Printf("value changed on key %v: new value=%v", key, pair.Value)
}
```
##Watching for events happening on child keys (WatchTree)
You can use watches to watch modifications on a key. First you need to check if the key exists. If this is not the case, we need to create it using the `Put` function. There is a special step here though if you want your code to work across backends. Because `etcd` is a special case and it makes the distinction between directories and keys, we need to make sure that the created key is considered as a directory by enforcing `IsDir` at `true`.
```go
// Checking on the key before watching
if !kv.Exists(key) {
// Don't forget IsDir:true if the code is used cross-backend
err := kv.Put(key, []byte("bar"), &store.WriteOptions{IsDir:true})
if err != nil {
fmt.Errorf("Something went wrong when initializing key %v", key)
}
}
stopCh := make(<-chan struct{})
events, err := kv.WatchTree(key, stopCh)
select {
case pairs := <-events:
// Do something with events
for _, pair := range pairs {
fmt.Printf("value changed on key %v: new value=%v", key, pair.Value)
}
}
```
## Distributed Locking, using Lock/Unlock
```go
key := "lockKey"
value := []byte("bar")
// Initialize a distributed lock. TTL is optional, it is here to make sure that
// the lock is released after the program that is holding the lock ends or crashes
lock, err := kv.NewLock(key, &store.LockOptions{Value: value, TTL: 2 * time.Second})
if err != nil {
fmt.Errorf("something went wrong when trying to initialize the Lock")
}
// Try to lock the key, the call to Lock() is blocking
_, err := lock.Lock(nil)
if err != nil {
fmt.Errorf("something went wrong when trying to lock key %v", key)
}
// Get should work because we are holding the key
pair, err := kv.Get(key)
if err != nil {
fmt.Errorf("key %v has value %v", key, pair.Value)
}
// Unlock the key
err = lock.Unlock()
if err != nil {
fmt.Errorf("something went wrong when trying to unlock key %v", key)
}
```
|