mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 07:00:12 +01:00
♻️ Refactor kernel model transaction https://github.com/siyuan-note/siyuan/issues/9338
This commit is contained in:
parent
828eeee4be
commit
56ace2e427
2 changed files with 21 additions and 50 deletions
|
|
@ -35,7 +35,6 @@ func StartCron() {
|
||||||
go every(2*time.Hour, model.StatJob)
|
go every(2*time.Hour, model.StatJob)
|
||||||
go every(2*time.Hour, model.RefreshCheckJob)
|
go every(2*time.Hour, model.RefreshCheckJob)
|
||||||
go every(3*time.Second, model.FlushUpdateRefTextRenameDocJob)
|
go every(3*time.Second, model.FlushUpdateRefTextRenameDocJob)
|
||||||
go every(50*time.Millisecond, model.FlushTxJob)
|
|
||||||
go every(util.SQLFlushInterval, sql.FlushTxJob)
|
go every(util.SQLFlushInterval, sql.FlushTxJob)
|
||||||
go every(util.SQLFlushInterval, sql.FlushHistoryTxJob)
|
go every(util.SQLFlushInterval, sql.FlushHistoryTxJob)
|
||||||
go every(util.SQLFlushInterval, sql.FlushAssetContentTxJob)
|
go every(util.SQLFlushInterval, sql.FlushAssetContentTxJob)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -65,11 +64,6 @@ func IsUnfoldHeading(transactions *[]*Transaction) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
txQueue []*Transaction
|
|
||||||
txQueueLock = sync.Mutex{}
|
|
||||||
)
|
|
||||||
|
|
||||||
func WaitForWritingFiles() {
|
func WaitForWritingFiles() {
|
||||||
var printLog bool
|
var printLog bool
|
||||||
var lastPrintLog bool
|
var lastPrintLog bool
|
||||||
|
|
@ -86,25 +80,34 @@ func WaitForWritingFiles() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
txQueue = make(chan *Transaction, 7)
|
||||||
|
flushLock = sync.Mutex{}
|
||||||
|
)
|
||||||
|
|
||||||
func isWritingFiles() bool {
|
func isWritingFiles() bool {
|
||||||
time.Sleep(time.Duration(20) * time.Millisecond)
|
time.Sleep(time.Duration(20) * time.Millisecond)
|
||||||
return 0 < len(txQueue) || util.IsMutexLocked(&txQueueLock) || util.IsMutexLocked(&flushLock)
|
return 0 < len(txQueue) || util.IsMutexLocked(&flushLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FlushTxJob() {
|
func init() {
|
||||||
flushTx()
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case tx := <-txQueue:
|
||||||
|
flushTx(tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var flushLock = sync.Mutex{}
|
func flushTx(tx *Transaction) {
|
||||||
|
|
||||||
func flushTx() {
|
|
||||||
defer logging.Recover()
|
defer logging.Recover()
|
||||||
flushLock.Lock()
|
flushLock.Lock()
|
||||||
defer flushLock.Unlock()
|
defer flushLock.Unlock()
|
||||||
|
|
||||||
currentTx := mergeTx()
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if txErr := performTx(currentTx); nil != txErr {
|
if txErr := performTx(tx); nil != txErr {
|
||||||
switch txErr.code {
|
switch txErr.code {
|
||||||
case TxErrCodeBlockNotFound:
|
case TxErrCodeBlockNotFound:
|
||||||
util.PushTxErr("Transaction failed", txErr.code, nil)
|
util.PushTxErr("Transaction failed", txErr.code, nil)
|
||||||
|
|
@ -116,48 +119,17 @@ func flushTx() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elapsed := time.Now().Sub(start).Milliseconds()
|
elapsed := time.Now().Sub(start).Milliseconds()
|
||||||
if 0 < len(currentTx.DoOperations) {
|
if 0 < len(tx.DoOperations) {
|
||||||
if 2000 < elapsed {
|
if 2000 < elapsed {
|
||||||
logging.LogWarnf("op tx [%dms]", elapsed)
|
logging.LogWarnf("op tx [%dms]", elapsed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeTx() (ret *Transaction) {
|
|
||||||
txQueueLock.Lock()
|
|
||||||
defer txQueueLock.Unlock()
|
|
||||||
|
|
||||||
ret = &Transaction{}
|
|
||||||
var doOps []*Operation
|
|
||||||
for _, tx := range txQueue {
|
|
||||||
for _, op := range tx.DoOperations {
|
|
||||||
if l := len(doOps); 0 < l {
|
|
||||||
lastOp := doOps[l-1]
|
|
||||||
if "update" == lastOp.Action && "update" == op.Action && lastOp.ID == op.ID { // 连续相同的更新操作
|
|
||||||
lastOp.discard = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doOps = append(doOps, op)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, op := range doOps {
|
|
||||||
if !op.discard {
|
|
||||||
ret.DoOperations = append(ret.DoOperations, op)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
txQueue = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func PerformTransactions(transactions *[]*Transaction) {
|
func PerformTransactions(transactions *[]*Transaction) {
|
||||||
txQueueLock.Lock()
|
for _, tx := range *transactions {
|
||||||
txQueue = append(txQueue, *transactions...)
|
txQueue <- tx
|
||||||
sort.Slice(txQueue, func(i, j int) bool {
|
}
|
||||||
return txQueue[i].Timestamp < txQueue[j].Timestamp
|
|
||||||
})
|
|
||||||
txQueueLock.Unlock()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue