mirror of
https://github.com/taigrr/bitcask
synced 2025-01-18 04:03:17 -08:00
Add flock on database Open()/Close() to prevent multiple concurrent processes write access. Fixes #2
This commit is contained in:
parent
f88919ecd0
commit
f4b7918e93
21
bitcask.go
21
bitcask.go
@ -11,6 +11,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofrs/flock"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -18,10 +20,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrKeyNotFound = errors.New("error: key not found")
|
ErrKeyNotFound = errors.New("error: key not found")
|
||||||
|
ErrCannotAcquireLock = errors.New("error: cannot acquire lock")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bitcask struct {
|
type Bitcask struct {
|
||||||
|
*flock.Flock
|
||||||
|
|
||||||
path string
|
path string
|
||||||
curr *Datafile
|
curr *Datafile
|
||||||
keydir *Keydir
|
keydir *Keydir
|
||||||
@ -31,6 +36,10 @@ type Bitcask struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bitcask) Close() error {
|
func (b *Bitcask) Close() error {
|
||||||
|
defer func() {
|
||||||
|
b.Flock.Unlock()
|
||||||
|
}()
|
||||||
|
|
||||||
for _, df := range b.datafiles {
|
for _, df := range b.datafiles {
|
||||||
df.Close()
|
df.Close()
|
||||||
}
|
}
|
||||||
@ -343,6 +352,7 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bitcask := &Bitcask{
|
bitcask := &Bitcask{
|
||||||
|
Flock: flock.New(filepath.Join(path, "lock")),
|
||||||
path: path,
|
path: path,
|
||||||
curr: curr,
|
curr: curr,
|
||||||
keydir: keydir,
|
keydir: keydir,
|
||||||
@ -358,5 +368,14 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
locked, err := bitcask.Flock.TryLock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !locked {
|
||||||
|
return nil, ErrCannotAcquireLock
|
||||||
|
}
|
||||||
|
|
||||||
return bitcask, nil
|
return bitcask, nil
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,21 @@ func TestMerge(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLocking(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
testdir, err := ioutil.TempDir("", "bitcask")
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
db, err := Open(testdir)
|
||||||
|
assert.NoError(err)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
_, err = Open(testdir)
|
||||||
|
assert.Error(err)
|
||||||
|
assert.Equal("error: cannot acquire lock", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkGet(b *testing.B) {
|
func BenchmarkGet(b *testing.B) {
|
||||||
testdir, err := ioutil.TempDir("", "bitcask")
|
testdir, err := ioutil.TempDir("", "bitcask")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
1
go.mod
1
go.mod
@ -1,6 +1,7 @@
|
|||||||
module github.com/prologic/bitcask
|
module github.com/prologic/bitcask
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gofrs/flock v0.7.1
|
||||||
github.com/gogo/protobuf v1.2.1
|
github.com/gogo/protobuf v1.2.1
|
||||||
github.com/golang/protobuf v1.2.0
|
github.com/golang/protobuf v1.2.0
|
||||||
github.com/gorilla/websocket v1.4.0 // indirect
|
github.com/gorilla/websocket v1.4.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -10,6 +10,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
|
||||||
|
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user