🎨 改进内核任务调度机制提升稳定性 https://github.com/siyuan-note/siyuan/issues/7113

This commit is contained in:
Liang Ding 2023-01-26 13:47:12 +08:00
parent db777afc25
commit 5aff312a7b
No known key found for this signature in database
GPG Key ID: 136F30F901A2231D
3 changed files with 64 additions and 54 deletions

View File

@ -25,6 +25,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/88250/gulu"
"github.com/88250/lute/ast" "github.com/88250/lute/ast"
"github.com/88250/lute/html" "github.com/88250/lute/html"
"github.com/88250/lute/parse" "github.com/88250/lute/parse"
@ -48,6 +49,42 @@ var autoFixLock = sync.Mutex{}
func autoFixIndex() { func autoFixIndex() {
defer logging.Recover() defer logging.Recover()
autoFixLock.Lock()
defer autoFixLock.Unlock()
// 去除重复的数据库块记录
duplicatedRootIDs := sql.GetDuplicatedRootIDs("blocks")
if 1 > len(duplicatedRootIDs) {
duplicatedRootIDs = sql.GetDuplicatedRootIDs("blocks_fts")
if 1 > len(duplicatedRootIDs) && !Conf.Search.CaseSensitive {
duplicatedRootIDs = sql.GetDuplicatedRootIDs("blocks_fts_case_insensitive")
}
}
roots := sql.GetBlocks(duplicatedRootIDs)
rootMap := map[string]*sql.Block{}
for _, root := range roots {
rootMap[root.ID] = root
}
for _, rootID := range duplicatedRootIDs {
root := rootMap[rootID]
if nil == root {
continue
}
//logging.LogWarnf("exist more than one tree [%s], reindex it", rootID)
sql.RemoveTreeQueue(root.Box, rootID)
if util.IsExiting {
break
}
}
if 0 < len(duplicatedRootIDs) {
logging.LogWarnf("exist more than one tree duplicated [%d], reindex it", len(duplicatedRootIDs))
}
sql.WaitForWritingDatabase()
// 根据文件系统补全块树 // 根据文件系统补全块树
boxes := Conf.GetOpenedBoxes() boxes := Conf.GetOpenedBoxes()
for _, box := range boxes { for _, box := range boxes {
@ -88,6 +125,8 @@ func autoFixIndex() {
} }
} }
sql.WaitForWritingDatabase()
// 清理已关闭的笔记本块树 // 清理已关闭的笔记本块树
boxes = Conf.GetClosedBoxes() boxes = Conf.GetClosedBoxes()
for _, box := range boxes { for _, box := range boxes {
@ -96,49 +135,17 @@ func autoFixIndex() {
// 对比块树和数据库并订正数据库 // 对比块树和数据库并订正数据库
rootUpdatedMap := treenode.GetRootUpdated() rootUpdatedMap := treenode.GetRootUpdated()
dbRootUpdatedMap, err := sql.GetRootUpdated("blocks") dbRootUpdatedMap, err := sql.GetRootUpdated()
if nil == err { if nil == err {
reindexTreeByUpdated(rootUpdatedMap, dbRootUpdatedMap, "blocks") reindexTreeByUpdated(rootUpdatedMap, dbRootUpdatedMap)
}
dbFtsRootUpdatedMap, err := sql.GetRootUpdated("blocks_fts")
if nil == err {
reindexTreeByUpdated(rootUpdatedMap, dbFtsRootUpdatedMap, "blocks_fts")
}
if !Conf.Search.CaseSensitive {
dbFtsRootUpdatedMap, err = sql.GetRootUpdated("blocks_fts_case_insensitive")
if nil == err {
reindexTreeByUpdated(rootUpdatedMap, dbFtsRootUpdatedMap, "blocks_fts_case_insensitive")
}
} }
// 去除重复的数据库块记录 sql.WaitForWritingDatabase()
duplicatedRootIDs := sql.GetDuplicatedRootIDs("blocks")
if 1 > len(duplicatedRootIDs) {
duplicatedRootIDs = sql.GetDuplicatedRootIDs("blocks_fts")
if 1 > len(duplicatedRootIDs) && !Conf.Search.CaseSensitive {
duplicatedRootIDs = sql.GetDuplicatedRootIDs("blocks_fts_case_insensitive")
}
}
size := len(duplicatedRootIDs)
for i, rootID := range duplicatedRootIDs {
root := sql.GetBlock(rootID)
if nil == root {
continue
}
logging.LogWarnf("exist more than one tree [%s], reindex it", rootID)
sql.RemoveTreeQueue(root.Box, rootID)
reindexTree(rootID, i, size)
if util.IsExiting {
break
}
}
util.PushStatusBar(Conf.Language(185)) util.PushStatusBar(Conf.Language(185))
} }
func reindexTreeByUpdated(rootUpdatedMap, dbRootUpdatedMap map[string]string, blocksTable string) { func reindexTreeByUpdated(rootUpdatedMap, dbRootUpdatedMap map[string]string) {
i := -1 i := -1
size := len(rootUpdatedMap) size := len(rootUpdatedMap)
for rootID, updated := range rootUpdatedMap { for rootID, updated := range rootUpdatedMap {
@ -174,16 +181,33 @@ func reindexTreeByUpdated(rootUpdatedMap, dbRootUpdatedMap map[string]string, bl
} }
} }
var rootIDs []string
for rootID, _ := range dbRootUpdatedMap { for rootID, _ := range dbRootUpdatedMap {
if _, ok := rootUpdatedMap[rootID]; !ok { if _, ok := rootUpdatedMap[rootID]; !ok {
logging.LogWarnf("tree [%s] is not in block tree, remove it from [%s]", rootID, blocksTable) rootIDs = append(rootIDs, rootID)
sql.DeleteTree(blocksTable, rootID)
} }
if util.IsExiting { if util.IsExiting {
break break
} }
} }
rootIDs = gulu.Str.RemoveDuplicatedElem(rootIDs)
roots := map[string]*sql.Block{}
blocks := sql.GetBlocks(rootIDs)
for _, block := range blocks {
roots[block.RootID] = block
}
for id, root := range roots {
if nil == root {
continue
}
logging.LogWarnf("tree [%s] is not in block tree, remove it from [%s]", id, root.Box)
sql.RemoveTreeQueue(root.Box, root.ID)
if util.IsExiting {
break
}
}
} }
func reindexTreeByPath(box, p string, i, size int) { func reindexTreeByPath(box, p string, i, size int) {

View File

@ -92,17 +92,3 @@ func UpdateBlockContent(block *Block) {
tx.Commit() tx.Commit()
putBlockCache(block) putBlockCache(block)
} }
func DeleteTree(table, rootID string) {
tx, err := beginTx()
if nil != err {
return
}
stmt := "DELETE FROM `" + table + "` WHERE root_id = ?"
if err = execStmtTx(tx, stmt, rootID); nil != err {
tx.Rollback()
return
}
tx.Commit()
}

View File

@ -597,8 +597,8 @@ func GetBlock(id string) (ret *Block) {
return return
} }
func GetRootUpdated(blocksTable string) (ret map[string]string, err error) { func GetRootUpdated() (ret map[string]string, err error) {
rows, err := query("SELECT root_id, updated FROM `" + blocksTable + "` WHERE type = 'd'") rows, err := query("SELECT root_id, updated FROM `blocks` WHERE type = 'd'")
if nil != err { if nil != err {
logging.LogErrorf("sql query failed: %s", err) logging.LogErrorf("sql query failed: %s", err)
return return