Skip to content

Instantly share code, notes, and snippets.

@buchanae
Last active May 31, 2017 02:33
Show Gist options
  • Save buchanae/38cc3c0ccb0a092417a14e7abdb4a0f8 to your computer and use it in GitHub Desktop.
Save buchanae/38cc3c0ccb0a092417a14e7abdb4a0f8 to your computer and use it in GitHub Desktop.
Trying to understand locking in BoltDB
package main
import "io/ioutil"
import "fmt"
import "github.com/boltdb/bolt"
import "sync"
import "time"
func update(id string, val string) func(*bolt.Tx) error {
return func(tx *bolt.Tx) error {
bkt := []byte(id)
if tx.Bucket(bkt) == nil {
tx.CreateBucket(bkt)
}
fmt.Println("Update enter")
b := tx.Bucket(bkt)
fmt.Println("Update bucket")
b.Put([]byte("key"), []byte(val))
fmt.Println("Update after put")
return nil
}
}
func view(id string) func(*bolt.Tx) error {
return func(tx *bolt.Tx) error {
fmt.Println("View enter")
bkt := []byte(id)
for i := 0; i < 5; i++ {
b := tx.Bucket(bkt)
fmt.Println("View after bucket", b)
if b != nil {
v := b.Get([]byte("key"))
fmt.Println("View after get", string(v))
}
time.Sleep(time.Millisecond * 500)
}
fmt.Println("view end")
return nil
}
}
func main() {
p, _ := ioutil.TempFile("", "test-bolt")
db, err := bolt.Open(p.Name(), 0600, &bolt.Options{
Timeout: time.Second * 5,
})
if err != nil {
panic(err)
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
db.View(view("bkt-1"))
wg.Done()
}()
time.Sleep(time.Second * 1)
wg.Add(1)
go func() {
uperr := db.Update(update("bkt-1", "val-2"))
fmt.Println("After update", "bkt-1", uperr)
wg.Done()
}()
wg.Add(1)
go func() {
uperr := db.Update(update("bkt-2", "val-2"))
fmt.Println("After update", "bkt-2", uperr)
wg.Done()
}()
wg.Add(1)
go func() {
db.View(view("bkt-1"))
wg.Done()
}()
wg.Wait()
}
package main
import "io/ioutil"
import "fmt"
import "github.com/boltdb/bolt"
import "sync"
import "time"
func update(prefix string, id string, val string) func(*bolt.Tx) error {
fmt.Println(prefix, "Call update", id, val)
return func(tx *bolt.Tx) error {
bkt := []byte(id)
if tx.Bucket(bkt) == nil {
tx.CreateBucket(bkt)
}
fmt.Println(prefix, "Update enter", id)
b := tx.Bucket(bkt)
fmt.Println(prefix, "Update bucket", id)
b.Put([]byte("key"), []byte(val))
fmt.Println(prefix, "Update after put", id, val)
return nil
}
}
func view(id string, wait chan bool) func(*bolt.Tx) error {
return func(tx *bolt.Tx) error {
fmt.Println("___ View enter", id)
bkt := []byte(id)
if wait != nil {
<-wait
}
b := tx.Bucket(bkt)
fmt.Println("___ View after bucket", id, b)
if b != nil {
v := b.Get([]byte("key"))
fmt.Println("___ View after get", id, string(v))
}
fmt.Println("___ View end", id)
return nil
}
}
func main() {
p, _ := ioutil.TempFile("", "test-bolt")
db, err := bolt.Open(p.Name(), 0600, &bolt.Options{
Timeout: time.Second * 5,
})
if err != nil {
panic(err)
}
var wg sync.WaitGroup
wait := make(chan bool)
wg.Add(1)
go func() {
db.View(view("bkt-1", wait))
wg.Done()
}()
for i := 0; i < 3; i++ {
time.Sleep(time.Millisecond)
wg.Add(1)
go func(i int) {
uperr := db.Update(update(">", "bkt-1", fmt.Sprint(i)))
if uperr != nil {
panic(uperr)
}
wg.Done()
}(i)
}
wg.Add(1)
go func() {
uperr := db.Update(update("++", "bkt-2", "val-2"))
if uperr != nil {
panic(uperr)
}
wg.Done()
}()
time.Sleep(time.Second * 5)
fmt.Println("Closing")
close(wait)
wg.Wait()
db.View(view("bkt-1", nil))
}
___ View enter bkt-1
> Call update bkt-1 0
> Update enter bkt-1
> Update bucket bkt-1
> Update after put bkt-1 0
> Call update bkt-1 1
> Update enter bkt-1
> Update bucket bkt-1
> Update after put bkt-1 1
> Call update bkt-1 2
++ Call update bkt-2 val-2
Closing
___ View after bucket bkt-1 <nil>
___ View end bkt-1
> Update enter bkt-1
> Update bucket bkt-1
> Update after put bkt-1 2
++ Update enter bkt-2
++ Update bucket bkt-2
++ Update after put bkt-2 val-2
___ View enter bkt-1
___ View after bucket bkt-1 &{0x1283035 0xc42008c2a0 map[] 0x1283045 <nil> map[] 0.5}
___ View after get bkt-1 2
___ View end bkt-1
View enter
View after bucket <nil>
View after bucket <nil>
View after bucket <nil>
Update enter
Update bucket
Update after put
View enter
View after bucket <nil>
After update bkt-1 <nil>
Update enter
Update bucket
Update after put
View after bucket <nil>
View after bucket <nil>
View after bucket <nil>
View after bucket <nil>
View after bucket <nil>
view end
View after bucket <nil>
view end
After update bkt-2 <nil>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment