mmm: lockfile to prevent multiple instances.
This commit is contained in:
35
eventstore/mmm/lockfile_test.go
Normal file
35
eventstore/mmm/lockfile_test.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package mmm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLockfile(t *testing.T) {
|
||||||
|
// create a temporary directory for the test
|
||||||
|
tmpDir, err := os.MkdirTemp("", "mmm-lockfile-test-*")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
|
// initialize first MMM instance
|
||||||
|
mmmm1 := &MultiMmapManager{Dir: tmpDir}
|
||||||
|
err = mmmm1.Init()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer mmmm1.Close()
|
||||||
|
|
||||||
|
// try to initialize second MMM instance on the same directory
|
||||||
|
mmmm2 := &MultiMmapManager{Dir: tmpDir}
|
||||||
|
err = mmmm2.Init()
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "already in use by another instance")
|
||||||
|
|
||||||
|
// close first instance
|
||||||
|
mmmm1.Close()
|
||||||
|
|
||||||
|
// now second instance should be able to open
|
||||||
|
err = mmmm2.Init()
|
||||||
|
require.NoError(t, err)
|
||||||
|
mmmm2.Close()
|
||||||
|
}
|
||||||
@@ -56,6 +56,15 @@ func (b *MultiMmapManager) Init() error {
|
|||||||
b.Logger = &nopLogger
|
b.Logger = &nopLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create lockfile to prevent multiple instances
|
||||||
|
lockfilePath := filepath.Join(b.Dir, "mmmm.lock")
|
||||||
|
if _, err := os.OpenFile(lockfilePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0644); err != nil {
|
||||||
|
if os.IsExist(err) {
|
||||||
|
return fmt.Errorf("database at %s is already in use by another instance", b.Dir)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("failed to create lockfile %s: %w", lockfilePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
// create directory if it doesn't exist
|
// create directory if it doesn't exist
|
||||||
dbpath := filepath.Join(b.Dir, "mmmm")
|
dbpath := filepath.Join(b.Dir, "mmmm")
|
||||||
if err := os.MkdirAll(dbpath, 0755); err != nil {
|
if err := os.MkdirAll(dbpath, 0755); err != nil {
|
||||||
@@ -333,4 +342,8 @@ func (b *MultiMmapManager) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
syscall.Munmap(b.mmapf)
|
syscall.Munmap(b.mmapf)
|
||||||
|
|
||||||
|
// remove lockfile
|
||||||
|
lockfilePath := filepath.Join(b.Dir, "mmmm.lock")
|
||||||
|
os.Remove(lockfilePath)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user