bi/platform-basic-libs/service/consumer_data/real_time_warehousing.go
1340691923@qq.com ebbf4120bf 第一次提交
2022-01-26 16:40:50 +08:00

112 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package consumer_data
import (
"context"
"github.com/1340691923/xwl_bi/engine/db"
"github.com/1340691923/xwl_bi/engine/logs"
jsoniter "github.com/json-iterator/go"
"github.com/olivere/elastic"
"go.uber.org/zap"
"sync"
"time"
)
type RealTimeWarehousing struct {
buffer []*elastic.BulkIndexRequest
bufferMutex *sync.RWMutex
batchSize int
flushInterval int
}
func NewRealTimeWarehousing(batchSize, flushInterval int) *RealTimeWarehousing {
realTimeWarehousing := &RealTimeWarehousing{
buffer: make([]*elastic.BulkIndexRequest, 0, batchSize),
bufferMutex: new(sync.RWMutex),
batchSize: batchSize,
flushInterval: flushInterval,
}
if flushInterval > 0 {
realTimeWarehousing.RegularFlushing()
}
return realTimeWarehousing
}
func (this *RealTimeWarehousing) Flush() (err error) {
this.bufferMutex.Lock()
if len(this.buffer) > 0 {
startNow := time.Now()
var json = jsoniter.ConfigCompatibleWithStandardLibrary
bulkRequest := db.EsClient.Bulk()
for _, buffer := range this.buffer {
bulkRequest.Add(buffer)
}
res, err := bulkRequest.Do(context.Background())
if err != nil {
logs.Logger.Error("ES出现错误休息10秒钟继续", zap.Error(err))
time.Sleep(time.Second * 10)
this.Flush()
} else {
if res.Errors {
resStr, _ := json.MarshalToString(res)
logs.Logger.Error("ES出现错误", zap.String("res", resStr))
} else {
lostTime := time.Now().Sub(startNow).String()
len := len(this.buffer)
if len > 0 {
logs.Logger.Info("ES入库成功", zap.String("所花时间", lostTime), zap.Int("数据长度为", len))
}
}
}
this.buffer = make([]*elastic.BulkIndexRequest, 0, this.batchSize)
}
this.bufferMutex.Unlock()
return nil
}
func (this *RealTimeWarehousing) Add(data *elastic.BulkIndexRequest) (err error) {
this.bufferMutex.Lock()
this.buffer = append(this.buffer, data)
this.bufferMutex.Unlock()
if this.getBufferLength() >= this.batchSize {
err := this.Flush()
return err
}
return nil
}
func (this *RealTimeWarehousing) getBufferLength() int {
this.bufferMutex.RLock()
defer this.bufferMutex.RUnlock()
return len(this.buffer)
}
func (this *RealTimeWarehousing) FlushAll() error {
for this.getBufferLength() > 0 {
if err := this.Flush(); err != nil {
return err
}
}
return nil
}
func (this *RealTimeWarehousing) RegularFlushing() {
go func() {
ticker := time.NewTicker(time.Duration(this.flushInterval) * time.Second)
defer ticker.Stop()
for {
<-ticker.C
if err := this.Flush(); err != nil {
logs.Logger.Error("RealTimeWarehousing RegularFlushing", zap.Error(err))
}
}
}()
}