c-go: Update diskv to get atomic fs cache write

This commit is contained in:
Antoine Pelisse 2017-08-08 15:05:16 -07:00
parent 332b681bd1
commit 30325cd580
12 changed files with 74 additions and 46 deletions

4
Godeps/Godeps.json generated
View File

@ -2254,8 +2254,8 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Comment": "v2.0.0-2-g5dfcb07",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Comment": "v2.0.1",
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pkg/errors",

View File

@ -256,7 +256,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pkg/errors",

View File

@ -508,7 +508,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pkg/errors",

View File

@ -248,7 +248,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pmezard/go-difflib/difflib",

View File

@ -228,7 +228,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/spf13/pflag",

View File

@ -264,7 +264,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pkg/errors",

View File

@ -128,7 +128,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/spf13/pflag",

View File

@ -256,7 +256,7 @@
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
},
{
"ImportPath": "github.com/pkg/errors",

View File

@ -1,16 +1,9 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["httpcache.go"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
@ -27,4 +20,5 @@ filegroup(
"//vendor/github.com/gregjones/httpcache/diskcache:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -1,16 +1,9 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["diskcache.go"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/peterbourgon/diskv:go_default_library"],
)
@ -25,4 +18,5 @@ filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -1,11 +1,4 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
@ -14,7 +7,7 @@ go_library(
"diskv.go",
"index.go",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/google/btree:go_default_library"],
)
@ -29,4 +22,5 @@ filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -46,6 +46,12 @@ type Options struct {
CacheSizeMax uint64 // bytes
PathPerm os.FileMode
FilePerm os.FileMode
// If TempDir is set, it will enable filesystem atomic writes by
// writing temporary files to that location before being moved
// to BasePath.
// Note that TempDir MUST be on the same device/partition as
// BasePath.
TempDir string
Index Index
IndexLess LessFunction
@ -115,41 +121,71 @@ func (d *Diskv) WriteStream(key string, r io.Reader, sync bool) error {
return d.writeStreamWithLock(key, r, sync)
}
// writeStream does no input validation checking.
// TODO: use atomic FS ops.
func (d *Diskv) writeStreamWithLock(key string, r io.Reader, sync bool) error {
if err := d.ensurePathWithLock(key); err != nil {
return fmt.Errorf("ensure path: %s", err)
// createKeyFileWithLock either creates the key file directly, or
// creates a temporary file in TempDir if it is set.
func (d *Diskv) createKeyFileWithLock(key string) (*os.File, error) {
if d.TempDir != "" {
if err := os.MkdirAll(d.TempDir, d.PathPerm); err != nil {
return nil, fmt.Errorf("temp mkdir: %s", err)
}
f, err := ioutil.TempFile(d.TempDir, "")
if err != nil {
return nil, fmt.Errorf("temp file: %s", err)
}
if err := f.Chmod(d.FilePerm); err != nil {
f.Close() // error deliberately ignored
os.Remove(f.Name()) // error deliberately ignored
return nil, fmt.Errorf("chmod: %s", err)
}
return f, nil
}
mode := os.O_WRONLY | os.O_CREATE | os.O_TRUNC // overwrite if exists
f, err := os.OpenFile(d.completeFilename(key), mode, d.FilePerm)
if err != nil {
return fmt.Errorf("open file: %s", err)
return nil, fmt.Errorf("open file: %s", err)
}
return f, nil
}
// writeStream does no input validation checking.
func (d *Diskv) writeStreamWithLock(key string, r io.Reader, sync bool) error {
if err := d.ensurePathWithLock(key); err != nil {
return fmt.Errorf("ensure path: %s", err)
}
f, err := d.createKeyFileWithLock(key)
if err != nil {
return fmt.Errorf("create key file: %s", err)
}
wc := io.WriteCloser(&nopWriteCloser{f})
if d.Compression != nil {
wc, err = d.Compression.Writer(f)
if err != nil {
f.Close() // error deliberately ignored
f.Close() // error deliberately ignored
os.Remove(f.Name()) // error deliberately ignored
return fmt.Errorf("compression writer: %s", err)
}
}
if _, err := io.Copy(wc, r); err != nil {
f.Close() // error deliberately ignored
f.Close() // error deliberately ignored
os.Remove(f.Name()) // error deliberately ignored
return fmt.Errorf("i/o copy: %s", err)
}
if err := wc.Close(); err != nil {
f.Close() // error deliberately ignored
f.Close() // error deliberately ignored
os.Remove(f.Name()) // error deliberately ignored
return fmt.Errorf("compression close: %s", err)
}
if sync {
if err := f.Sync(); err != nil {
f.Close() // error deliberately ignored
f.Close() // error deliberately ignored
os.Remove(f.Name()) // error deliberately ignored
return fmt.Errorf("file sync: %s", err)
}
}
@ -158,6 +194,13 @@ func (d *Diskv) writeStreamWithLock(key string, r io.Reader, sync bool) error {
return fmt.Errorf("file close: %s", err)
}
if f.Name() != d.completeFilename(key) {
if err := os.Rename(f.Name(), d.completeFilename(key)); err != nil {
os.Remove(f.Name()) // error deliberately ignored
return fmt.Errorf("rename: %s", err)
}
}
if d.Index != nil {
d.Index.Insert(key)
}
@ -390,6 +433,9 @@ func (d *Diskv) EraseAll() error {
defer d.mu.Unlock()
d.cache = make(map[string][]byte)
d.cacheSize = 0
if d.TempDir != "" {
os.RemoveAll(d.TempDir) // errors ignored
}
return os.RemoveAll(d.BasePath)
}