🐛 短时间内多次修改文档定义块标题后动态锚文本没有跟随 Fix https://github.com/siyuan-note/siyuan/issues/6330

This commit is contained in:
Liang Ding 2022-10-24 17:43:21 +08:00
parent 29a14f722d
commit 055a8b5981
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
2 changed files with 39 additions and 22 deletions

View file

@ -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
}

View file

@ -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 {