Files
open-im-server/pkg/common/db/unrelation/batch_insert_chat.go
T

172 lines
6.6 KiB
Go
Raw Normal View History

2023-01-28 13:19:36 +08:00
package unrelation
2022-05-20 11:00:11 +08:00
import (
"Open_IM/pkg/common/config"
2022-07-22 17:51:17 +08:00
"Open_IM/pkg/common/constant"
2023-01-16 20:14:26 +08:00
"Open_IM/pkg/common/db"
2022-05-20 11:00:11 +08:00
"Open_IM/pkg/common/log"
2022-09-14 19:36:59 +08:00
promePkg "Open_IM/pkg/common/prometheus"
2022-07-20 21:04:05 +08:00
pbMsg "Open_IM/pkg/proto/msg"
2022-05-20 11:00:11 +08:00
"Open_IM/pkg/utils"
"context"
"errors"
2022-06-15 16:50:45 +08:00
go_redis "github.com/go-redis/redis/v8"
2022-05-20 11:00:11 +08:00
"github.com/golang/protobuf/proto"
"go.mongodb.org/mongo-driver/bson"
2022-05-26 12:10:30 +08:00
"go.mongodb.org/mongo-driver/mongo"
2022-05-20 11:00:11 +08:00
)
2023-01-16 20:14:26 +08:00
func (d *db.DataBases) BatchInsertChat2DB(userID string, msgList []*pbMsg.MsgDataToMQ, operationID string, currentMaxSeq uint64) error {
2022-05-24 17:52:29 +08:00
newTime := getCurrentTimestampByMill()
if len(msgList) > GetSingleGocMsgNum() {
return errors.New("too large")
}
isInit := false
var remain uint64
blk0 := uint64(GetSingleGocMsgNum() - 1)
2022-08-10 14:01:26 +08:00
//currentMaxSeq 4998
2023-01-16 20:14:26 +08:00
if currentMaxSeq < uint64(mongo2.GetSingleGocMsgNum()) {
2022-08-10 14:01:26 +08:00
remain = blk0 - currentMaxSeq //1
2022-05-24 17:52:29 +08:00
} else {
2022-08-10 14:01:26 +08:00
excludeBlk0 := currentMaxSeq - blk0 //=1
//(5000-1)%5000 == 4999
2023-01-16 20:14:26 +08:00
remain = (uint64(mongo2.GetSingleGocMsgNum()) - (excludeBlk0 % uint64(mongo2.GetSingleGocMsgNum()))) % uint64(mongo2.GetSingleGocMsgNum())
2022-05-24 17:52:29 +08:00
}
2022-08-10 14:01:26 +08:00
//remain=1
2022-05-24 17:52:29 +08:00
insertCounter := uint64(0)
2023-01-16 20:14:26 +08:00
msgListToMongo := make([]mongo2.MsgInfo, 0)
msgListToMongoNext := make([]mongo2.MsgInfo, 0)
2022-05-24 17:52:29 +08:00
seqUid := ""
seqUidNext := ""
log.Debug(operationID, "remain ", remain, "insertCounter ", insertCounter, "currentMaxSeq ", currentMaxSeq, userID, len(msgList))
var err error
for _, m := range msgList {
log.Debug(operationID, "msg node ", m.String(), m.MsgData.ClientMsgID)
currentMaxSeq++
2023-01-16 20:14:26 +08:00
sMsg := mongo2.MsgInfo{}
2022-05-24 17:52:29 +08:00
sMsg.SendTime = m.MsgData.SendTime
m.MsgData.Seq = uint32(currentMaxSeq)
2022-08-10 13:29:12 +08:00
log.Debug(operationID, "mongo msg node ", m.String(), m.MsgData.ClientMsgID, "userID: ", userID, "seq: ", currentMaxSeq)
2022-05-24 17:52:29 +08:00
if sMsg.Msg, err = proto.Marshal(m.MsgData); err != nil {
return utils.Wrap(err, "")
}
if isInit {
msgListToMongoNext = append(msgListToMongoNext, sMsg)
2023-01-16 20:14:26 +08:00
seqUidNext = mongo2.getSeqUid(userID, uint32(currentMaxSeq))
2022-05-24 17:52:29 +08:00
log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
continue
}
if insertCounter < remain {
msgListToMongo = append(msgListToMongo, sMsg)
insertCounter++
2023-01-16 20:14:26 +08:00
seqUid = mongo2.getSeqUid(userID, uint32(currentMaxSeq))
2022-08-10 14:15:45 +08:00
log.Debug(operationID, "msgListToMongo ", seqUid, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain, "userID: ", userID)
2022-05-24 17:52:29 +08:00
} else {
msgListToMongoNext = append(msgListToMongoNext, sMsg)
2023-01-16 20:14:26 +08:00
seqUidNext = mongo2.getSeqUid(userID, uint32(currentMaxSeq))
2022-08-10 14:15:45 +08:00
log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain, "userID: ", userID)
2022-05-24 17:52:29 +08:00
}
}
ctx := context.Background()
2023-01-16 20:14:26 +08:00
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(mongo2.cChat)
2022-05-24 17:52:29 +08:00
if seqUid != "" {
filter := bson.M{"uid": seqUid}
2022-08-10 14:15:45 +08:00
log.NewDebug(operationID, "filter ", seqUid, "list ", msgListToMongo, "userID: ", userID)
2022-05-24 17:52:29 +08:00
err := c.FindOneAndUpdate(ctx, filter, bson.M{"$push": bson.M{"msg": bson.M{"$each": msgListToMongo}}}).Err()
if err != nil {
2022-05-26 12:10:30 +08:00
if err == mongo.ErrNoDocuments {
filter := bson.M{"uid": seqUid}
2023-01-16 20:14:26 +08:00
sChat := mongo2.UserChat{}
2022-05-26 12:10:30 +08:00
sChat.UID = seqUid
sChat.Msg = msgListToMongo
log.NewDebug(operationID, "filter ", seqUid, "list ", msgListToMongo)
if _, err = c.InsertOne(ctx, &sChat); err != nil {
2022-09-14 21:11:40 +08:00
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
2022-05-26 12:10:30 +08:00
log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
return utils.Wrap(err, "")
}
2022-09-14 21:11:40 +08:00
promePkg.PromeInc(promePkg.MsgInsertMongoSuccessCounter)
2022-05-26 12:10:30 +08:00
} else {
2022-09-14 21:11:40 +08:00
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
2022-05-26 12:10:30 +08:00
log.Error(operationID, "FindOneAndUpdate failed ", err.Error(), filter)
return utils.Wrap(err, "")
}
2022-09-19 11:10:37 +08:00
} else {
promePkg.PromeInc(promePkg.MsgInsertMongoSuccessCounter)
2022-05-24 17:52:29 +08:00
}
}
if seqUidNext != "" {
filter := bson.M{"uid": seqUidNext}
2023-01-16 20:14:26 +08:00
sChat := mongo2.UserChat{}
2022-05-24 17:52:29 +08:00
sChat.UID = seqUidNext
sChat.Msg = msgListToMongoNext
2022-08-10 14:15:45 +08:00
log.NewDebug(operationID, "filter ", seqUidNext, "list ", msgListToMongoNext, "userID: ", userID)
2022-05-24 17:52:29 +08:00
if _, err = c.InsertOne(ctx, &sChat); err != nil {
2022-09-14 21:11:40 +08:00
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
2022-05-24 17:52:29 +08:00
log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
return utils.Wrap(err, "")
}
2022-09-14 21:11:40 +08:00
promePkg.PromeInc(promePkg.MsgInsertMongoSuccessCounter)
2022-05-24 17:52:29 +08:00
}
2023-01-16 20:14:26 +08:00
log.Debug(operationID, "batch mgo cost time ", mongo2.getCurrentTimestampByMill()-newTime, userID, len(msgList))
2022-05-24 17:52:29 +08:00
return nil
}
2023-01-16 20:14:26 +08:00
func (d *db.DataBases) BatchInsertChat2Cache(insertID string, msgList []*pbMsg.MsgDataToMQ, operationID string) (error, uint64) {
newTime := mongo2.getCurrentTimestampByMill()
2022-07-22 17:51:17 +08:00
lenList := len(msgList)
2023-01-16 20:14:26 +08:00
if lenList > mongo2.GetSingleGocMsgNum() {
2022-05-24 17:52:29 +08:00
return errors.New("too large"), 0
}
2022-07-22 17:51:17 +08:00
if lenList < 1 {
return errors.New("too short as 0"), 0
}
// judge sessionType to get seq
var currentMaxSeq uint64
var err error
if msgList[0].MsgData.SessionType == constant.SuperGroupChatType {
currentMaxSeq, err = d.GetGroupMaxSeq(insertID)
2022-08-10 14:01:26 +08:00
log.Debug(operationID, "constant.SuperGroupChatType lastMaxSeq before add ", currentMaxSeq, "userID ", insertID, err)
2022-05-24 17:52:29 +08:00
} else {
2022-07-22 17:51:17 +08:00
currentMaxSeq, err = d.GetUserMaxSeq(insertID)
2022-08-10 14:01:26 +08:00
log.Debug(operationID, "constant.SingleChatType lastMaxSeq before add ", currentMaxSeq, "userID ", insertID, err)
2022-07-22 17:51:17 +08:00
}
if err != nil && err != go_redis.Nil {
2022-09-14 19:36:59 +08:00
promePkg.PromeInc(promePkg.SeqGetFailedCounter)
2022-05-24 17:52:29 +08:00
return utils.Wrap(err, ""), 0
}
2022-09-14 19:36:59 +08:00
promePkg.PromeInc(promePkg.SeqGetSuccessCounter)
2022-05-24 17:52:29 +08:00
2022-07-22 17:51:17 +08:00
lastMaxSeq := currentMaxSeq
2022-05-24 17:52:29 +08:00
for _, m := range msgList {
2022-08-10 13:29:12 +08:00
2022-05-24 17:52:29 +08:00
currentMaxSeq++
2023-01-16 20:14:26 +08:00
sMsg := mongo2.MsgInfo{}
2022-05-24 17:52:29 +08:00
sMsg.SendTime = m.MsgData.SendTime
m.MsgData.Seq = uint32(currentMaxSeq)
2022-08-10 13:29:12 +08:00
log.Debug(operationID, "cache msg node ", m.String(), m.MsgData.ClientMsgID, "userID: ", insertID, "seq: ", currentMaxSeq)
2022-05-24 17:52:29 +08:00
}
2022-07-22 17:51:17 +08:00
log.Debug(operationID, "SetMessageToCache ", insertID, len(msgList))
2022-09-14 19:36:59 +08:00
err, failedNum := d.SetMessageToCache(msgList, insertID, operationID)
2022-05-24 17:52:29 +08:00
if err != nil {
2022-09-14 19:36:59 +08:00
promePkg.PromeAdd(promePkg.MsgInsertRedisFailedCounter, failedNum)
2022-07-22 17:51:17 +08:00
log.Error(operationID, "setMessageToCache failed, continue ", err.Error(), len(msgList), insertID)
2022-09-14 19:36:59 +08:00
} else {
promePkg.PromeInc(promePkg.MsgInsertRedisSuccessCounter)
2022-07-22 17:51:17 +08:00
}
2023-01-16 20:14:26 +08:00
log.Debug(operationID, "batch to redis cost time ", mongo2.getCurrentTimestampByMill()-newTime, insertID, len(msgList))
2022-07-22 17:51:17 +08:00
if msgList[0].MsgData.SessionType == constant.SuperGroupChatType {
err = d.SetGroupMaxSeq(insertID, currentMaxSeq)
} else {
err = d.SetUserMaxSeq(insertID, currentMaxSeq)
2022-05-24 17:52:29 +08:00
}
2022-09-14 19:36:59 +08:00
if err != nil {
promePkg.PromeInc(promePkg.SeqSetFailedCounter)
} else {
promePkg.PromeInc(promePkg.SeqSetSuccessCounter)
}
2022-07-22 17:51:17 +08:00
return utils.Wrap(err, ""), lastMaxSeq
2022-05-24 17:52:29 +08:00
}