From 055a8b598155e3914f44faf81cbd763793bb531d Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Mon, 24 Oct 2022 17:43:21 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E7=9F=AD=E6=97=B6=E9=97=B4=E5=86=85?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=9D=97=E6=A0=87=E9=A2=98=E5=90=8E=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E9=94=9A=E6=96=87=E6=9C=AC=E6=B2=A1=E6=9C=89=E8=B7=9F=E9=9A=8F?= =?UTF-8?q?=20Fix=20https://github.com/siyuan-note/siyuan/issues/6330?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/file.go | 29 ++++++++++------------------- kernel/model/transaction.go | 32 +++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index c50d7bc99..f30bd15a2 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -1282,6 +1282,15 @@ func RenameDoc(boxID, p, title string) (err error) { title = "Untitled" } + oldHPath := tree.HPath + tree.HPath = path.Join(path.Dir(tree.HPath), title) + tree.Root.SetIALAttr("title", title) + tree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) + + if err = renameWriteJSONQueue(tree, oldHPath); nil != err { + return + } + refText := getNodeRefText(tree.Root) evt := util.NewCmdResult("rename", 0, util.PushModeBroadcast, util.PushModeNone) evt.Data = map[string]interface{}{ @@ -1293,26 +1302,8 @@ func RenameDoc(boxID, p, title string) (err error) { } util.PushEvent(evt) - oldHPath := tree.HPath - tree.HPath = path.Join(path.Dir(tree.HPath), title) - tree.Root.SetIALAttr("title", title) - tree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) - - if err = renameWriteJSONQueue(tree, oldHPath); nil != err { - return - } - box.renameSubTrees(tree) - changedDefs := map[string]*ast.Node{tree.ID: tree.Root} - changedTrees := map[string]*parse.Tree{tree.ID: tree} - - // 引用文档时锚文本没有跟随文档重命名 https://github.com/siyuan-note/siyuan/issues/4193 - // 详见 refreshDynamicRefText 函数实现 - go func() { - sql.WaitForWritingDatabase() - refreshDynamicRefText(changedDefs, changedTrees) - }() - + go updateRefTextRenameDoc(tree) IncSync() return } diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 10bd0b730..3803004d4 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -100,6 +100,7 @@ func isWritingFiles() bool { } func AutoFlushTx() { + go autoFlushUpdateRefTextRenameDoc() for { flushTx() time.Sleep(time.Duration(txDelay) * time.Millisecond) @@ -1060,9 +1061,6 @@ func (tx *Transaction) writeTree(tree *parse.Tree) (err error) { func refreshDynamicRefText(updatedDefNodes map[string]*ast.Node, updatedTrees map[string]*parse.Tree) { // 这个实现依赖了数据库缓存,导致外部调用时可能需要阻塞等待数据库写入后才能获取到 refs - // 比如通过块引创建文档后立即重命名文档,这时引用关系还没有入库,所以重命名查询不到引用关系,最终导致动态锚文本设置失败 - // 引用文档时锚文本没有跟随文档重命名 https://github.com/siyuan-note/siyuan/issues/4193 - // 解决方案是将重命名通过协程异步调用,详见 RenameDoc 函数 treeRefNodeIDs := map[string]*hashset.Set{} for _, updateNode := range updatedDefNodes { @@ -1126,6 +1124,34 @@ func refreshDynamicRefText(updatedDefNodes map[string]*ast.Node, updatedTrees ma } } +var updateRefTextRenameDocs = map[string]*parse.Tree{} +var updateRefTextRenameDocLock = sync.Mutex{} + +func updateRefTextRenameDoc(renamedTree *parse.Tree) { + updateRefTextRenameDocLock.Lock() + updateRefTextRenameDocs[renamedTree.ID] = renamedTree + updateRefTextRenameDocLock.Unlock() +} + +func autoFlushUpdateRefTextRenameDoc() { + for { + sql.WaitForWritingDatabase() + flushUpdateRefTextRenameDoc() + } +} + +func flushUpdateRefTextRenameDoc() { + updateRefTextRenameDocLock.Lock() + defer updateRefTextRenameDocLock.Unlock() + + for _, tree := range updateRefTextRenameDocs { + changedDefs := map[string]*ast.Node{tree.ID: tree.Root} + changedTrees := map[string]*parse.Tree{tree.ID: tree} + refreshDynamicRefText(changedDefs, changedTrees) + } + updateRefTextRenameDocs = map[string]*parse.Tree{} +} + func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (changed bool) { ast.Walk(refNode, func(n *ast.Node, entering bool) ast.WalkStatus { if !entering {