diff --git a/dir_other.go b/dir_other.go new file mode 100644 index 000000000..d80490327 --- /dev/null +++ b/dir_other.go @@ -0,0 +1,109 @@ +//go:build js || wasip1 +// +build js wasip1 + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/dgraph-io/badger/v4/y" +) + +// directoryLockGuard holds a lock on a directory and a pid file inside. The pid file isn't part +// of the locking mechanism, it's just advisory. +type directoryLockGuard struct { + // File handle on the directory, which we've flocked. + f *os.File + // The absolute path to our pid file. + path string + // Was this a shared lock for a read-only database? + readOnly bool +} + +// acquireDirectoryLock gets a lock on the directory (using flock). If +// this is not read-only, it will also write our pid to +// dirPath/pidFileName for convenience. +func acquireDirectoryLock(dirPath string, pidFileName string, readOnly bool) ( + *directoryLockGuard, error) { + // Convert to absolute path so that Release still works even if we do an unbalanced + // chdir in the meantime. + absPidFilePath, err := filepath.Abs(filepath.Join(dirPath, pidFileName)) + if err != nil { + return nil, y.Wrapf(err, "cannot get absolute path for pid lock file") + } + f, err := os.Open(dirPath) + if err != nil { + return nil, y.Wrapf(err, "cannot open directory %q", dirPath) + } + + // NOTE: Here is where we would normally call flock. + // This is not supported in js / wasm, so skip it. + + if !readOnly { + // Yes, we happily overwrite a pre-existing pid file. We're the + // only read-write badger process using this directory. + err = os.WriteFile(absPidFilePath, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0666) + if err != nil { + f.Close() + return nil, y.Wrapf(err, + "Cannot write pid file %q", absPidFilePath) + } + } + + return &directoryLockGuard{f, absPidFilePath, readOnly}, nil +} + +// Release deletes the pid file and releases our lock on the directory. +func (guard *directoryLockGuard) release() error { + var err error + if !guard.readOnly { + // It's important that we remove the pid file first. + err = os.Remove(guard.path) + } + + if closeErr := guard.f.Close(); err == nil { + err = closeErr + } + guard.path = "" + guard.f = nil + + return err +} + +// openDir opens a directory for syncing. +func openDir(path string) (*os.File, error) { return os.Open(path) } + +// When you create or delete a file, you have to ensure the directory entry for the file is synced +// in order to guarantee the file is visible (if the system crashes). (See the man page for fsync, +// or see https://github.com/coreos/etcd/issues/6368 for an example.) +func syncDir(dir string) error { + f, err := openDir(dir) + if err != nil { + return y.Wrapf(err, "While opening directory: %s.", dir) + } + + err = f.Sync() + closeErr := f.Close() + if err != nil { + return y.Wrapf(err, "While syncing directory: %s.", dir) + } + return y.Wrapf(closeErr, "While closing directory: %s.", dir) +} diff --git a/dir_unix.go b/dir_unix.go index ecaa5ced7..d7a7199e9 100644 --- a/dir_unix.go +++ b/dir_unix.go @@ -1,5 +1,5 @@ -//go:build !windows && !plan9 -// +build !windows,!plan9 +//go:build !windows && !plan9 && !js && !wasip1 +// +build !windows,!plan9,!js,!wasip1 /* * Copyright 2017 Dgraph Labs, Inc. and Contributors diff --git a/go.mod b/go.mod index 7621ec15b..fbc924c92 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,9 @@ module github.com/dgraph-io/badger/v4 go 1.19 +// https://github.com/dgraph-io/ristretto/pull/375 +replace github.com/dgraph-io/ristretto => github.com/paralin/ristretto v0.1.2-0.20240221033725-e9838e36e9d8 // fix-wasm-1 + require ( github.com/cespare/xxhash/v2 v2.2.0 github.com/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91 diff --git a/go.sum b/go.sum index c72a4a773..7f96889ff 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91 h1:Pux6+xANi0I7RRo5E1gflI4EZ2yx3BGZ75JkAIvGEOA= -github.com/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91/go.mod h1:swkazRqnUf1N62d0Nutz7KIj2UKqsm/H8tD0nBJAXqM= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -34,6 +32,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/paralin/ristretto v0.1.2-0.20240221033725-e9838e36e9d8 h1:EfAnHCpOmoIZXrAV8Ov3Z32tJw3K62rFdlQOSNYAU04= +github.com/paralin/ristretto v0.1.2-0.20240221033725-e9838e36e9d8/go.mod h1:swkazRqnUf1N62d0Nutz7KIj2UKqsm/H8tD0nBJAXqM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/y/file_dsync.go b/y/file_dsync.go index 1e171733e..3fb6537ca 100644 --- a/y/file_dsync.go +++ b/y/file_dsync.go @@ -1,5 +1,5 @@ -//go:build !dragonfly && !freebsd && !windows && !plan9 -// +build !dragonfly,!freebsd,!windows,!plan9 +//go:build !dragonfly && !freebsd && !windows && !plan9 && !js && !wasip1 +// +build !dragonfly,!freebsd,!windows,!plan9,!js,!wasip1 /* * Copyright 2017 Dgraph Labs, Inc. and Contributors