From 11e4c88f5a135b7ab6d51d2eccf260e3474afdf4 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 18 Sep 2022 09:14:34 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20=E7=BB=86=E5=8C=96=E4=BA=91=E7=AB=AF?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=94=81=E6=8F=90=E5=8D=87=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E6=80=A7=20https://github.com/siyuan-note/siyuan/issues/5887?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/asset.go | 3 +- kernel/api/extension.go | 3 +- kernel/bazaar/package.go | 3 +- kernel/filesys/io.go | 67 +++++++++++++++++++++++++++++++++++++ kernel/model/assets.go | 7 ++-- kernel/model/box.go | 9 ++--- kernel/model/export.go | 5 +-- kernel/model/file.go | 6 ++-- kernel/model/history.go | 11 +++--- kernel/model/import.go | 10 +++--- kernel/model/mount.go | 9 ++--- kernel/model/repository.go | 5 +-- kernel/model/sync.go | 5 +-- kernel/model/upload.go | 5 +-- kernel/util/file.go | 68 -------------------------------------- 15 files changed, 110 insertions(+), 106 deletions(-) create mode 100644 kernel/filesys/io.go diff --git a/kernel/api/asset.go b/kernel/api/asset.go index b3ae4bd9f..59e3a2704 100644 --- a/kernel/api/asset.go +++ b/kernel/api/asset.go @@ -24,6 +24,7 @@ import ( "github.com/88250/gulu" "github.com/gin-gonic/gin" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -85,7 +86,7 @@ func setFileAnnotation(c *gin.Context) { ret.Msg = err.Error() return } - if err := util.WriteFileSafer(writePath, []byte(data)); nil != err { + if err := filesys.WriteFileSafer(writePath, []byte(data)); nil != err { ret.Code = -1 ret.Msg = err.Error() return diff --git a/kernel/api/extension.go b/kernel/api/extension.go index 90fca65fd..78746e0f6 100644 --- a/kernel/api/extension.go +++ b/kernel/api/extension.go @@ -30,6 +30,7 @@ import ( "github.com/88250/lute/ast" "github.com/gin-gonic/gin" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -106,7 +107,7 @@ func extensionCopy(c *gin.Context) { } fName = fName + "-" + ast.NewNodeID() + ext writePath := filepath.Join(assets, fName) - if err = util.WriteFileSafer(writePath, data); nil != err { + if err = filesys.WriteFileSafer(writePath, data); nil != err { ret.Code = -1 ret.Msg = err.Error() break diff --git a/kernel/bazaar/package.go b/kernel/bazaar/package.go index 61577c9d0..544efae8c 100644 --- a/kernel/bazaar/package.go +++ b/kernel/bazaar/package.go @@ -32,6 +32,7 @@ import ( "github.com/imroc/req/v3" "github.com/siyuan-note/httpclient" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/util" textUnicode "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" @@ -374,7 +375,7 @@ func installPackage(data []byte, installPath string) (err error) { } } srcPath := filepath.Join(unzipPath, dir) - if err = util.Copy(srcPath, installPath); nil != err { + if err = filesys.Copy(srcPath, installPath); nil != err { return } return diff --git a/kernel/filesys/io.go b/kernel/filesys/io.go new file mode 100644 index 000000000..fd9edb4cd --- /dev/null +++ b/kernel/filesys/io.go @@ -0,0 +1,67 @@ +package filesys + +import ( + "io" + "os" + "sync" + + "github.com/88250/gulu" + "github.com/siyuan-note/filelock" + "github.com/siyuan-note/logging" +) + +var writingFileLock = sync.Mutex{} + +func LockWriteFile() { + writingFileLock.Lock() +} + +func UnlockWriteFile() { + writingFileLock.Unlock() +} + +func WriteFileSaferByReader(writePath string, reader io.Reader) (err error) { + writingFileLock.Lock() + defer writingFileLock.Unlock() + + if err = gulu.File.WriteFileSaferByReader(writePath, reader, 0644); nil != err { + logging.LogErrorf("write file [%s] failed: %s", writePath, err) + return + } + return +} + +func WriteFileSafer(writePath string, data []byte) (err error) { + writingFileLock.Lock() + defer writingFileLock.Unlock() + + if err = gulu.File.WriteFileSafer(writePath, data, 0644); nil != err { + logging.LogErrorf("write file [%s] failed: %s", writePath, err) + return + } + return +} + +func Copy(source, dest string) (err error) { + writingFileLock.Lock() + defer writingFileLock.Unlock() + + filelock.ReleaseFileLocks(source) + if err = gulu.File.Copy(source, dest); nil != err { + logging.LogErrorf("copy [%s] to [%s] failed: %s", source, dest, err) + return + } + return +} + +func RemoveAll(p string) (err error) { + writingFileLock.Lock() + defer writingFileLock.Unlock() + + filelock.ReleaseFileLocks(p) + if err = os.RemoveAll(p); nil != err { + logging.LogErrorf("remove all [%s] failed: %s", p, err) + return + } + return +} diff --git a/kernel/model/assets.go b/kernel/model/assets.go index 19c69dcbc..23aa82e12 100644 --- a/kernel/model/assets.go +++ b/kernel/model/assets.go @@ -39,6 +39,7 @@ import ( "github.com/siyuan-note/httpclient" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/cache" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/search" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" @@ -141,7 +142,7 @@ func NetImg2LocalAssets(rootID string) (err error) { name = util.FilterFileName(name) name = "net-img-" + name + "-" + ast.NewNodeID() + ext writePath := filepath.Join(util.DataDir, "assets", name) - if err = util.WriteFileSafer(writePath, data); nil != err { + if err = filesys.WriteFileSafer(writePath, data); nil != err { logging.LogErrorf("write downloaded net img [%s] to local assets [%s] failed: %s", u, writePath, err) return ast.WalkSkipChildren } @@ -383,7 +384,7 @@ func saveWorkspaceAssets(assets []string) { logging.LogErrorf("create assets conf failed: %s", err) return } - if err = util.WriteFileSafer(confPath, data); nil != err { + if err = filesys.WriteFileSafer(confPath, data); nil != err { logging.LogErrorf("write assets conf failed: %s", err) return } @@ -478,7 +479,7 @@ func RenameAsset(oldPath, newName string) (err error) { newName = util.AssetName(newName) + filepath.Ext(oldPath) newPath := "assets/" + newName - if err = util.Copy(filepath.Join(util.DataDir, oldPath), filepath.Join(util.DataDir, newPath)); nil != err { + if err = filesys.Copy(filepath.Join(util.DataDir, oldPath), filepath.Join(util.DataDir, newPath)); nil != err { logging.LogErrorf("copy asset [%s] failed: %s", oldPath, err) return } diff --git a/kernel/model/box.go b/kernel/model/box.go index b7a9e10e1..360f4039d 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -35,6 +35,7 @@ import ( "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/conf" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" @@ -202,7 +203,7 @@ func (box *Box) saveConf0(data []byte) { if err := os.MkdirAll(filepath.Join(util.DataDir, box.ID, ".siyuan"), 0755); nil != err { logging.LogErrorf("save box conf [%s] failed: %s", confPath, err) } - if err := util.WriteFileSafer(confPath, data); nil != err { + if err := filesys.WriteFileSafer(confPath, data); nil != err { logging.LogErrorf("save box conf [%s] failed: %s", confPath, err) } } @@ -292,8 +293,8 @@ func (box *Box) Move(oldPath, newPath string) error { toPath := filepath.Join(boxLocalPath, newPath) filelock.ReleaseFileLocks(fromPath) - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() if err := os.Rename(fromPath, toPath); nil != err { msg := fmt.Sprintf(Conf.Language(5), box.Name, fromPath, err) logging.LogErrorf("move [path=%s] in box [%s] failed: %s", fromPath, box.Name, err) @@ -313,7 +314,7 @@ func (box *Box) Move(oldPath, newPath string) error { func (box *Box) Remove(path string) error { boxLocalPath := filepath.Join(util.DataDir, box.ID) filePath := filepath.Join(boxLocalPath, path) - if err := util.RemoveAll(filePath); nil != err { + if err := filesys.RemoveAll(filePath); nil != err { msg := fmt.Sprintf(Conf.Language(7), box.Name, path, err) logging.LogErrorf("remove [path=%s] in box [%s] failed: %s", path, box.ID, err) return errors.New(msg) diff --git a/kernel/model/export.go b/kernel/model/export.go index 8f8d49c53..0724e3715 100644 --- a/kernel/model/export.go +++ b/kernel/model/export.go @@ -42,6 +42,7 @@ import ( "github.com/emirpasic/gods/stacks/linkedliststack" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" @@ -158,8 +159,8 @@ func exportData(exportFolder string) (err error) { return } - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() err = filelock.ReleaseAllFileLocks() if nil != err { diff --git a/kernel/model/file.go b/kernel/model/file.go index a55f3a9fa..a06de1821 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -1203,7 +1203,7 @@ func RemoveDoc(boxID, p string) (err error) { historyPath := filepath.Join(historyDir, boxID, p) absPath := filepath.Join(util.DataDir, boxID, p) - if err = util.Copy(absPath, historyPath); nil != err { + if err = filesys.Copy(absPath, historyPath); nil != err { return errors.New(fmt.Sprintf(Conf.Language(70), box.Name, absPath, err)) } @@ -1534,8 +1534,8 @@ func ChangeFileTreeSort(boxID string, paths []string) { } WaitForWritingFiles() - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() box := Conf.Box(boxID) sortIDs := map[string]int{} diff --git a/kernel/model/history.go b/kernel/model/history.go index de99d7045..b3f334e8f 100644 --- a/kernel/model/history.go +++ b/kernel/model/history.go @@ -37,6 +37,7 @@ import ( "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/conf" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/search" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" @@ -238,7 +239,7 @@ func RollbackDocHistory(boxID, historyPath string) (err error) { } WaitForWritingFiles() - util.LockWriteFile() + filesys.LockWriteFile() srcPath := historyPath var destPath string @@ -249,22 +250,22 @@ func RollbackDocHistory(boxID, historyPath string) (err error) { workingDoc := treenode.GetBlockTree(id) if nil != workingDoc { if err = os.RemoveAll(filepath.Join(util.DataDir, boxID, workingDoc.Path)); nil != err { - util.UnlockWriteFile() + filesys.UnlockWriteFile() return } } destPath, err = getRollbackDockPath(boxID, historyPath) if nil != err { - util.UnlockWriteFile() + filesys.UnlockWriteFile() return } if err = gulu.File.Copy(srcPath, destPath); nil != err { - util.UnlockWriteFile() + filesys.UnlockWriteFile() return } - util.UnlockWriteFile() + filesys.UnlockWriteFile() FullReindex() IncSync() diff --git a/kernel/model/import.go b/kernel/model/import.go index 83755d4c1..ed575f8bb 100644 --- a/kernel/model/import.go +++ b/kernel/model/import.go @@ -259,7 +259,7 @@ func ImportSY(zipPath, boxID, toPath string) (err error) { for _, assets := range assetsDirs { if gulu.File.IsDir(assets) { dataAssets := filepath.Join(util.DataDir, "assets") - if err = util.Copy(assets, dataAssets); nil != err { + if err = filesys.Copy(assets, dataAssets); nil != err { logging.LogErrorf("copy assets from [%s] to [%s] failed: %s", assets, dataAssets, err) return } @@ -267,8 +267,8 @@ func ImportSY(zipPath, boxID, toPath string) (err error) { os.RemoveAll(assets) } - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() filelock.ReleaseAllFileLocks() @@ -331,8 +331,8 @@ func ImportData(zipPath string) (err error) { return errors.New("invalid data.zip") } - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() filelock.ReleaseAllFileLocks() tmpDataPath := filepath.Join(unzipPath, dirs[0].Name()) diff --git a/kernel/model/mount.go b/kernel/model/mount.go index 8d8782f5c..7dbf82931 100644 --- a/kernel/model/mount.go +++ b/kernel/model/mount.go @@ -29,13 +29,12 @@ import ( "github.com/88250/lute/ast" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" ) func CreateBox(name string) (id string, err error) { - WaitForWritingFiles() - id = ast.NewNodeID() boxLocalPath := filepath.Join(util.DataDir, id) err = os.MkdirAll(boxLocalPath, 0755) @@ -52,10 +51,6 @@ func CreateBox(name string) (id string, err error) { } func RenameBox(boxID, name string) (err error) { - WaitForWritingFiles() - util.LockWriteFile() - defer util.UnlockWriteFile() - box := Conf.Box(boxID) if nil == box { return errors.New(Conf.Language(0)) @@ -103,7 +98,7 @@ func RemoveBox(boxID string) (err error) { } unmount0(boxID) - if err = os.RemoveAll(localPath); nil != err { + if err = filesys.RemoveAll(localPath); nil != err { return } IncSync() diff --git a/kernel/model/repository.go b/kernel/model/repository.go index 24a37a016..7ed86cd58 100644 --- a/kernel/model/repository.go +++ b/kernel/model/repository.go @@ -40,6 +40,7 @@ import ( "github.com/siyuan-note/httpclient" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/cache" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" @@ -221,8 +222,8 @@ func CheckoutRepo(id string) (err error) { } util.PushEndlessProgress(Conf.Language(63)) - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() WaitForWritingFiles() sql.WaitForWritingDatabase() filelock.ReleaseAllFileLocks() diff --git a/kernel/model/sync.go b/kernel/model/sync.go index fb92c70f8..2e961dc65 100644 --- a/kernel/model/sync.go +++ b/kernel/model/sync.go @@ -32,6 +32,7 @@ import ( "github.com/dustin/go-humanize" "github.com/siyuan-note/dejavu" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" @@ -63,8 +64,8 @@ func SyncData(boot, exit, byHand bool) { return } - util.LockWriteFile() - defer util.UnlockWriteFile() + filesys.LockWriteFile() + defer filesys.UnlockWriteFile() if util.IsMutexLocked(&syncLock) { logging.LogWarnf("sync is in progress") diff --git a/kernel/model/upload.go b/kernel/model/upload.go index d82ba02e5..fd4ce9860 100644 --- a/kernel/model/upload.go +++ b/kernel/model/upload.go @@ -28,6 +28,7 @@ import ( "github.com/88250/lute/ast" "github.com/gin-gonic/gin" "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" @@ -85,7 +86,7 @@ func InsertLocalAssets(id string, assetPaths []string) (succMap map[string]inter f.Close() return } - if err = util.WriteFileSaferByReader(writePath, f); nil != err { + if err = filesys.WriteFileSaferByReader(writePath, f); nil != err { f.Close() return } @@ -168,7 +169,7 @@ func Upload(c *gin.Context) { f.Close() break } - if err = util.WriteFileSaferByReader(writePath, f); nil != err { + if err = filesys.WriteFileSaferByReader(writePath, f); nil != err { errFiles = append(errFiles, fName) ret.Msg = err.Error() f.Close() diff --git a/kernel/util/file.go b/kernel/util/file.go index 85e21ea77..174db57d0 100644 --- a/kernel/util/file.go +++ b/kernel/util/file.go @@ -17,85 +17,17 @@ package util import ( - "io" "os" "path" "path/filepath" "sort" "strings" - "sync" "github.com/88250/gulu" "github.com/88250/lute/ast" - "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" ) -var writingFileLock = sync.Mutex{} - -func LockWriteFile() { - if IsMutexLocked(&writingFileLock) { - logging.LogWarnf("write file is locked") - return - } - - writingFileLock.Lock() -} - -func UnlockWriteFile() { - if !IsMutexLocked(&writingFileLock) { - logging.LogWarnf("write file is not locked") - return - } - writingFileLock.Unlock() -} - -func WriteFileSaferByReader(writePath string, reader io.Reader) (err error) { - writingFileLock.Lock() - defer writingFileLock.Unlock() - - if err = gulu.File.WriteFileSaferByReader(writePath, reader, 0644); nil != err { - logging.LogErrorf("write file [%s] failed: %s", writePath, err) - return - } - return -} - -func WriteFileSafer(writePath string, data []byte) (err error) { - writingFileLock.Lock() - defer writingFileLock.Unlock() - - if err = gulu.File.WriteFileSafer(writePath, data, 0644); nil != err { - logging.LogErrorf("write file [%s] failed: %s", writePath, err) - return - } - return -} - -func Copy(source, dest string) (err error) { - writingFileLock.Lock() - defer writingFileLock.Unlock() - - filelock.ReleaseFileLocks(source) - if err = gulu.File.Copy(source, dest); nil != err { - logging.LogErrorf("copy [%s] to [%s] failed: %s", source, dest, err) - return - } - return -} - -func RemoveAll(p string) (err error) { - writingFileLock.Lock() - defer writingFileLock.Unlock() - - filelock.ReleaseFileLocks(p) - if err = os.RemoveAll(p); nil != err { - logging.LogErrorf("remove all [%s] failed: %s", p, err) - return - } - return -} - func IsEmptyDir(p string) bool { if !gulu.File.IsDir(p) { return false