|
|
|
@ -4,6 +4,7 @@ import (
|
|
|
|
|
"Open_IM/pkg/common/config"
|
|
|
|
|
"Open_IM/pkg/common/constant"
|
|
|
|
|
"Open_IM/pkg/common/log"
|
|
|
|
|
promePkg "Open_IM/pkg/common/prometheus"
|
|
|
|
|
pbMsg "Open_IM/pkg/proto/msg"
|
|
|
|
|
"Open_IM/pkg/utils"
|
|
|
|
|
"context"
|
|
|
|
@ -14,10 +15,6 @@ import (
|
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (d *DataBases) BatchDeleteChat2DB(userID string, msgList []*pbMsg.MsgDataToMQ, operationID string) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *DataBases) BatchInsertChat2DB(userID string, msgList []*pbMsg.MsgDataToMQ, operationID string, currentMaxSeq uint64) error {
|
|
|
|
|
newTime := getCurrentTimestampByMill()
|
|
|
|
|
if len(msgList) > GetSingleGocMsgNum() {
|
|
|
|
@ -85,10 +82,13 @@ func (d *DataBases) BatchInsertChat2DB(userID string, msgList []*pbMsg.MsgDataTo
|
|
|
|
|
sChat.Msg = msgListToMongo
|
|
|
|
|
log.NewDebug(operationID, "filter ", seqUid, "list ", msgListToMongo)
|
|
|
|
|
if _, err = c.InsertOne(ctx, &sChat); err != nil {
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
|
|
|
|
|
log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertMongoSuccessCounter)
|
|
|
|
|
} else {
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
|
|
|
|
|
log.Error(operationID, "FindOneAndUpdate failed ", err.Error(), filter)
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
@ -101,9 +101,11 @@ func (d *DataBases) BatchInsertChat2DB(userID string, msgList []*pbMsg.MsgDataTo
|
|
|
|
|
sChat.Msg = msgListToMongoNext
|
|
|
|
|
log.NewDebug(operationID, "filter ", seqUidNext, "list ", msgListToMongoNext, "userID: ", userID)
|
|
|
|
|
if _, err = c.InsertOne(ctx, &sChat); err != nil {
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertMongoFailedCounter)
|
|
|
|
|
log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertMongoSuccessCounter)
|
|
|
|
|
}
|
|
|
|
|
log.Debug(operationID, "batch mgo cost time ", getCurrentTimestampByMill()-newTime, userID, len(msgList))
|
|
|
|
|
return nil
|
|
|
|
@ -129,8 +131,11 @@ func (d *DataBases) BatchInsertChat2Cache(insertID string, msgList []*pbMsg.MsgD
|
|
|
|
|
log.Debug(operationID, "constant.SingleChatType lastMaxSeq before add ", currentMaxSeq, "userID ", insertID, err)
|
|
|
|
|
}
|
|
|
|
|
if err != nil && err != go_redis.Nil {
|
|
|
|
|
promePkg.PromeInc(promePkg.SeqGetFailedCounter)
|
|
|
|
|
return utils.Wrap(err, ""), 0
|
|
|
|
|
}
|
|
|
|
|
promePkg.PromeInc(promePkg.SeqGetSuccessCounter)
|
|
|
|
|
promePkg.SeqGetSuccessCounter.Inc()
|
|
|
|
|
|
|
|
|
|
lastMaxSeq := currentMaxSeq
|
|
|
|
|
for _, m := range msgList {
|
|
|
|
@ -142,9 +147,12 @@ func (d *DataBases) BatchInsertChat2Cache(insertID string, msgList []*pbMsg.MsgD
|
|
|
|
|
log.Debug(operationID, "cache msg node ", m.String(), m.MsgData.ClientMsgID, "userID: ", insertID, "seq: ", currentMaxSeq)
|
|
|
|
|
}
|
|
|
|
|
log.Debug(operationID, "SetMessageToCache ", insertID, len(msgList))
|
|
|
|
|
err = d.SetMessageToCache(msgList, insertID, operationID)
|
|
|
|
|
err, failedNum := d.SetMessageToCache(msgList, insertID, operationID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
promePkg.PromeAdd(promePkg.MsgInsertRedisFailedCounter, failedNum)
|
|
|
|
|
log.Error(operationID, "setMessageToCache failed, continue ", err.Error(), len(msgList), insertID)
|
|
|
|
|
} else {
|
|
|
|
|
promePkg.PromeInc(promePkg.MsgInsertRedisSuccessCounter)
|
|
|
|
|
}
|
|
|
|
|
log.Debug(operationID, "batch to redis cost time ", getCurrentTimestampByMill()-newTime, insertID, len(msgList))
|
|
|
|
|
if msgList[0].MsgData.SessionType == constant.SuperGroupChatType {
|
|
|
|
@ -152,6 +160,11 @@ func (d *DataBases) BatchInsertChat2Cache(insertID string, msgList []*pbMsg.MsgD
|
|
|
|
|
} else {
|
|
|
|
|
err = d.SetUserMaxSeq(insertID, currentMaxSeq)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
promePkg.PromeInc(promePkg.SeqSetFailedCounter)
|
|
|
|
|
} else {
|
|
|
|
|
promePkg.PromeInc(promePkg.SeqSetSuccessCounter)
|
|
|
|
|
}
|
|
|
|
|
return utils.Wrap(err, ""), lastMaxSeq
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -171,106 +184,100 @@ func (d *DataBases) BatchInsertChat2Cache(insertID string, msgList []*pbMsg.MsgD
|
|
|
|
|
// }
|
|
|
|
|
// return nil, lastMaxSeq
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
func (d *DataBases) BatchInsertChat(userID string, msgList []*pbMsg.MsgDataToMQ, operationID string) error {
|
|
|
|
|
newTime := getCurrentTimestampByMill()
|
|
|
|
|
if len(msgList) > GetSingleGocMsgNum() {
|
|
|
|
|
return errors.New("too large")
|
|
|
|
|
}
|
|
|
|
|
isInit := false
|
|
|
|
|
currentMaxSeq, err := d.GetUserMaxSeq(userID)
|
|
|
|
|
if err == nil {
|
|
|
|
|
|
|
|
|
|
} else if err == go_redis.Nil {
|
|
|
|
|
isInit = true
|
|
|
|
|
currentMaxSeq = 0
|
|
|
|
|
} else {
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
var remain uint64
|
|
|
|
|
//
|
|
|
|
|
//func (d *DataBases) BatchInsertChat(userID string, msgList []*pbMsg.MsgDataToMQ, operationID string) error {
|
|
|
|
|
// newTime := getCurrentTimestampByMill()
|
|
|
|
|
// if len(msgList) > GetSingleGocMsgNum() {
|
|
|
|
|
// return errors.New("too large")
|
|
|
|
|
// }
|
|
|
|
|
// isInit := false
|
|
|
|
|
// currentMaxSeq, err := d.GetUserMaxSeq(userID)
|
|
|
|
|
// if err == nil {
|
|
|
|
|
//
|
|
|
|
|
// } else if err == go_redis.Nil {
|
|
|
|
|
// isInit = true
|
|
|
|
|
// currentMaxSeq = 0
|
|
|
|
|
// } else {
|
|
|
|
|
// return utils.Wrap(err, "")
|
|
|
|
|
// }
|
|
|
|
|
// var remain uint64
|
|
|
|
|
// //if currentMaxSeq < uint64(GetSingleGocMsgNum()) {
|
|
|
|
|
// // remain = uint64(GetSingleGocMsgNum()-1) - (currentMaxSeq % uint64(GetSingleGocMsgNum()))
|
|
|
|
|
// //} else {
|
|
|
|
|
// // remain = uint64(GetSingleGocMsgNum()) - ((currentMaxSeq - (uint64(GetSingleGocMsgNum()) - 1)) % uint64(GetSingleGocMsgNum()))
|
|
|
|
|
// //}
|
|
|
|
|
//
|
|
|
|
|
// blk0 := uint64(GetSingleGocMsgNum() - 1)
|
|
|
|
|
// if currentMaxSeq < uint64(GetSingleGocMsgNum()) {
|
|
|
|
|
// remain = uint64(GetSingleGocMsgNum()-1) - (currentMaxSeq % uint64(GetSingleGocMsgNum()))
|
|
|
|
|
// remain = blk0 - currentMaxSeq
|
|
|
|
|
// } else {
|
|
|
|
|
// remain = uint64(GetSingleGocMsgNum()) - ((currentMaxSeq - (uint64(GetSingleGocMsgNum()) - 1)) % uint64(GetSingleGocMsgNum()))
|
|
|
|
|
// excludeBlk0 := currentMaxSeq - blk0
|
|
|
|
|
// remain = (uint64(GetSingleGocMsgNum()) - (excludeBlk0 % uint64(GetSingleGocMsgNum()))) % uint64(GetSingleGocMsgNum())
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// insertCounter := uint64(0)
|
|
|
|
|
// msgListToMongo := make([]MsgInfo, 0)
|
|
|
|
|
// msgListToMongoNext := make([]MsgInfo, 0)
|
|
|
|
|
// seqUid := ""
|
|
|
|
|
// seqUidNext := ""
|
|
|
|
|
// log.Debug(operationID, "remain ", remain, "insertCounter ", insertCounter, "currentMaxSeq ", currentMaxSeq, userID, len(msgList))
|
|
|
|
|
// //4998 remain ==1
|
|
|
|
|
// //4999
|
|
|
|
|
// for _, m := range msgList {
|
|
|
|
|
// log.Debug(operationID, "msg node ", m.String(), m.MsgData.ClientMsgID)
|
|
|
|
|
// currentMaxSeq++
|
|
|
|
|
// sMsg := MsgInfo{}
|
|
|
|
|
// sMsg.SendTime = m.MsgData.SendTime
|
|
|
|
|
// m.MsgData.Seq = uint32(currentMaxSeq)
|
|
|
|
|
// if sMsg.Msg, err = proto.Marshal(m.MsgData); err != nil {
|
|
|
|
|
// return utils.Wrap(err, "")
|
|
|
|
|
// }
|
|
|
|
|
// if isInit {
|
|
|
|
|
// msgListToMongoNext = append(msgListToMongoNext, sMsg)
|
|
|
|
|
// seqUidNext = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
// log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
// if insertCounter < remain {
|
|
|
|
|
// msgListToMongo = append(msgListToMongo, sMsg)
|
|
|
|
|
// insertCounter++
|
|
|
|
|
// seqUid = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
// log.Debug(operationID, "msgListToMongo ", seqUid, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
// } else {
|
|
|
|
|
// msgListToMongoNext = append(msgListToMongoNext, sMsg)
|
|
|
|
|
// seqUidNext = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
// log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// // ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
|
|
|
|
//
|
|
|
|
|
// ctx := context.Background()
|
|
|
|
|
// c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
|
|
|
|
|
//
|
|
|
|
|
// if seqUid != "" {
|
|
|
|
|
// filter := bson.M{"uid": seqUid}
|
|
|
|
|
// log.NewDebug(operationID, "filter ", seqUid, "list ", msgListToMongo)
|
|
|
|
|
// err := c.FindOneAndUpdate(ctx, filter, bson.M{"$push": bson.M{"msg": bson.M{"$each": msgListToMongo}}}).Err()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error(operationID, "FindOneAndUpdate failed ", err.Error(), filter)
|
|
|
|
|
// return utils.Wrap(err, "")
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// if seqUidNext != "" {
|
|
|
|
|
// filter := bson.M{"uid": seqUidNext}
|
|
|
|
|
// sChat := UserChat{}
|
|
|
|
|
// sChat.UID = seqUidNext
|
|
|
|
|
// sChat.Msg = msgListToMongoNext
|
|
|
|
|
// log.NewDebug(operationID, "filter ", seqUidNext, "list ", msgListToMongoNext)
|
|
|
|
|
// if _, err = c.InsertOne(ctx, &sChat); err != nil {
|
|
|
|
|
// log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
|
|
|
|
|
// return utils.Wrap(err, "")
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// log.NewWarn(operationID, "batch mgo cost time ", getCurrentTimestampByMill()-newTime, userID, len(msgList))
|
|
|
|
|
// return utils.Wrap(d.SetUserMaxSeq(userID, uint64(currentMaxSeq)), "")
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
blk0 := uint64(GetSingleGocMsgNum() - 1)
|
|
|
|
|
if currentMaxSeq < uint64(GetSingleGocMsgNum()) {
|
|
|
|
|
remain = blk0 - currentMaxSeq
|
|
|
|
|
} else {
|
|
|
|
|
excludeBlk0 := currentMaxSeq - blk0
|
|
|
|
|
remain = (uint64(GetSingleGocMsgNum()) - (excludeBlk0 % uint64(GetSingleGocMsgNum()))) % uint64(GetSingleGocMsgNum())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
insertCounter := uint64(0)
|
|
|
|
|
msgListToMongo := make([]MsgInfo, 0)
|
|
|
|
|
msgListToMongoNext := make([]MsgInfo, 0)
|
|
|
|
|
seqUid := ""
|
|
|
|
|
seqUidNext := ""
|
|
|
|
|
log.Debug(operationID, "remain ", remain, "insertCounter ", insertCounter, "currentMaxSeq ", currentMaxSeq, userID, len(msgList))
|
|
|
|
|
//4998 remain ==1
|
|
|
|
|
//4999
|
|
|
|
|
for _, m := range msgList {
|
|
|
|
|
log.Debug(operationID, "msg node ", m.String(), m.MsgData.ClientMsgID)
|
|
|
|
|
currentMaxSeq++
|
|
|
|
|
sMsg := MsgInfo{}
|
|
|
|
|
sMsg.SendTime = m.MsgData.SendTime
|
|
|
|
|
m.MsgData.Seq = uint32(currentMaxSeq)
|
|
|
|
|
if sMsg.Msg, err = proto.Marshal(m.MsgData); err != nil {
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
if isInit {
|
|
|
|
|
msgListToMongoNext = append(msgListToMongoNext, sMsg)
|
|
|
|
|
seqUidNext = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if insertCounter < remain {
|
|
|
|
|
msgListToMongo = append(msgListToMongo, sMsg)
|
|
|
|
|
insertCounter++
|
|
|
|
|
seqUid = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
log.Debug(operationID, "msgListToMongo ", seqUid, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
} else {
|
|
|
|
|
msgListToMongoNext = append(msgListToMongoNext, sMsg)
|
|
|
|
|
seqUidNext = getSeqUid(userID, uint32(currentMaxSeq))
|
|
|
|
|
log.Debug(operationID, "msgListToMongoNext ", seqUidNext, m.MsgData.Seq, m.MsgData.ClientMsgID, insertCounter, remain)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
|
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
|
|
|
|
|
|
|
|
|
|
if seqUid != "" {
|
|
|
|
|
filter := bson.M{"uid": seqUid}
|
|
|
|
|
log.NewDebug(operationID, "filter ", seqUid, "list ", msgListToMongo)
|
|
|
|
|
err := c.FindOneAndUpdate(ctx, filter, bson.M{"$push": bson.M{"msg": bson.M{"$each": msgListToMongo}}}).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error(operationID, "FindOneAndUpdate failed ", err.Error(), filter)
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if seqUidNext != "" {
|
|
|
|
|
filter := bson.M{"uid": seqUidNext}
|
|
|
|
|
sChat := UserChat{}
|
|
|
|
|
sChat.UID = seqUidNext
|
|
|
|
|
sChat.Msg = msgListToMongoNext
|
|
|
|
|
log.NewDebug(operationID, "filter ", seqUidNext, "list ", msgListToMongoNext)
|
|
|
|
|
if _, err = c.InsertOne(ctx, &sChat); err != nil {
|
|
|
|
|
log.NewError(operationID, "InsertOne failed", filter, err.Error(), sChat)
|
|
|
|
|
return utils.Wrap(err, "")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.NewWarn(operationID, "batch mgo cost time ", getCurrentTimestampByMill()-newTime, userID, len(msgList))
|
|
|
|
|
return utils.Wrap(d.SetUserMaxSeq(userID, uint64(currentMaxSeq)), "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//func (d *DataBases)setMessageToCache(msgList []*pbMsg.MsgDataToMQ, uid string) (err error) {
|
|
|
|
|
//
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
func (d *DataBases) GetFromCacheAndInsertDB(msgUserIDPrefix string) {
|
|
|
|
|
//get value from redis
|
|
|
|
|
|
|
|
|
|
//batch insert to db
|
|
|
|
|
}
|
|
|
|
|