fix: dir duplicate creation (close #1687)

This commit is contained in:
Noah Hsu 2022-09-19 13:43:23 +08:00
parent 5548ab62ac
commit d8dc8d8623

View File

@ -181,11 +181,15 @@ func Other(ctx context.Context, storage driver.Driver, args model.FsOtherArgs) (
} }
} }
var mkdirG singleflight.Group[interface{}]
func MakeDir(ctx context.Context, storage driver.Driver, path string) error { func MakeDir(ctx context.Context, storage driver.Driver, path string) error {
if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { if storage.Config().CheckStatus && storage.GetStorage().Status != WORK {
return errors.Errorf("storage not init: %s", storage.GetStorage().Status) return errors.Errorf("storage not init: %s", storage.GetStorage().Status)
} }
path = utils.StandardizePath(path) path = utils.StandardizePath(path)
key := Key(storage, path)
_, err, _ := mkdirG.Do(key, func() (interface{}, error) {
// check if dir exists // check if dir exists
f, err := Get(ctx, storage, path) f, err := Get(ctx, storage, path)
if err != nil { if err != nil {
@ -193,30 +197,33 @@ func MakeDir(ctx context.Context, storage driver.Driver, path string) error {
parentPath, dirName := stdpath.Split(path) parentPath, dirName := stdpath.Split(path)
err = MakeDir(ctx, storage, parentPath) err = MakeDir(ctx, storage, parentPath)
if err != nil { if err != nil {
return errors.WithMessagef(err, "failed to make parent dir [%s]", parentPath) return nil, errors.WithMessagef(err, "failed to make parent dir [%s]", parentPath)
} }
parentDir, err := Get(ctx, storage, parentPath) parentDir, err := Get(ctx, storage, parentPath)
// this should not happen // this should not happen
if err != nil { if err != nil {
return errors.WithMessagef(err, "failed to get parent dir [%s]", parentPath) return nil, errors.WithMessagef(err, "failed to get parent dir [%s]", parentPath)
} }
err = storage.MakeDir(ctx, parentDir, dirName) err = storage.MakeDir(ctx, parentDir, dirName)
if err == nil { if err == nil {
ClearCache(storage, parentPath) ClearCache(storage, parentPath)
} }
return errors.WithStack(err) return nil, errors.WithStack(err)
} else { } else {
return errors.WithMessage(err, "failed to check if dir exists") return nil, errors.WithMessage(err, "failed to check if dir exists")
} }
} else { } else {
// dir exists // dir exists
if f.IsDir() { if f.IsDir() {
return nil return nil, nil
} else { } else {
// dir to make is a file // dir to make is a file
return errors.New("file exists") return nil, errors.New("file exists")
} }
} }
})
return err
} }
func Move(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string) error { func Move(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string) error {