优化结构
This commit is contained in:
@@ -1,121 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
dataScopeAuditQueueSize = 1024
|
||||
dataScopeAuditBatchSize = 100
|
||||
dataScopeAuditInterval = 2 * time.Second
|
||||
)
|
||||
|
||||
// dataScopeAuditWriter keeps row-scope auditing best-effort: callbacks only
|
||||
// enqueue, while a background worker writes batches to the active database.
|
||||
type dataScopeAuditWriter struct {
|
||||
data *Data
|
||||
logger *slog.Logger
|
||||
queue chan dataAccessLogPO
|
||||
batchSize int
|
||||
interval time.Duration
|
||||
stop chan struct{}
|
||||
done chan struct{}
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func newDataScopeAuditWriter(data *Data, logger *slog.Logger) *dataScopeAuditWriter {
|
||||
return newDataScopeAuditWriterWithOptions(data, logger, dataScopeAuditQueueSize, dataScopeAuditBatchSize, dataScopeAuditInterval)
|
||||
}
|
||||
|
||||
func newDataScopeAuditWriterWithOptions(data *Data, logger *slog.Logger, queueSize, batchSize int, interval time.Duration) *dataScopeAuditWriter {
|
||||
w := &dataScopeAuditWriter{
|
||||
data: data,
|
||||
logger: logger,
|
||||
queue: make(chan dataAccessLogPO, queueSize),
|
||||
batchSize: batchSize,
|
||||
interval: interval,
|
||||
stop: make(chan struct{}),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
go w.run()
|
||||
return w
|
||||
}
|
||||
|
||||
func (d *Data) enqueueDataScopeAudit(record dataAccessLogPO) {
|
||||
if d == nil || d.auditLog == nil {
|
||||
return
|
||||
}
|
||||
d.auditLog.Enqueue(record)
|
||||
}
|
||||
|
||||
func (w *dataScopeAuditWriter) Enqueue(record dataAccessLogPO) {
|
||||
if w == nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case w.queue <- record:
|
||||
default:
|
||||
w.log().Warn("数据权限审计缓冲已满, 事件被丢弃", "mod", "data-scope", "event_type", record.EventType, "table", record.TargetTable)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *dataScopeAuditWriter) Close() {
|
||||
if w == nil {
|
||||
return
|
||||
}
|
||||
w.closeOnce.Do(func() { close(w.stop) })
|
||||
<-w.done
|
||||
}
|
||||
|
||||
func (w *dataScopeAuditWriter) run() {
|
||||
defer close(w.done)
|
||||
ticker := time.NewTicker(w.interval)
|
||||
defer ticker.Stop()
|
||||
batch := make([]dataAccessLogPO, 0, w.batchSize)
|
||||
flush := func() {
|
||||
if len(batch) == 0 || w.data == nil || w.data.gormDB == nil {
|
||||
return
|
||||
}
|
||||
db := w.data.gormDB.DB()
|
||||
if db == nil {
|
||||
return
|
||||
}
|
||||
if err := db.WithContext(context.Background()).Session(&gorm.Session{NewDB: true, SkipHooks: true}).Create(&batch).Error; err != nil {
|
||||
w.log().Warn("数据权限审计批量写入失败", "mod", "data-scope", "error", err)
|
||||
}
|
||||
batch = batch[:0]
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case record := <-w.queue:
|
||||
batch = append(batch, record)
|
||||
if len(batch) >= w.batchSize {
|
||||
flush()
|
||||
}
|
||||
case <-ticker.C:
|
||||
flush()
|
||||
case <-w.stop:
|
||||
for {
|
||||
select {
|
||||
case record := <-w.queue:
|
||||
batch = append(batch, record)
|
||||
default:
|
||||
flush()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *dataScopeAuditWriter) log() *slog.Logger {
|
||||
if w != nil && w.logger != nil {
|
||||
return w.logger
|
||||
}
|
||||
return slog.Default()
|
||||
}
|
||||
Reference in New Issue
Block a user