Files
rootandClaude Opus 4.7 79ac89b458 Initial commit
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-11-07 10:47:18 +08:00

103 lines
2.1 KiB
Go

package mongos
import (
"context"
"time"
"videoweb/pub/models/utils"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
const notFindMsg = "mongo: no documents in result"
type lid struct {
db *Collection // 数据库连接
businessId string // 业务id
ch chan int64 // id缓冲池
min, max int64 // id段最小值,最大值
}
// newLid 创建一个lid,db:数据库连接;businessId:业务id;len:缓冲池大小
func newLid(db *Collection, businessId string, len int) (*lid, error) {
lid := lid{
db: db,
businessId: businessId,
ch: make(chan int64, len),
}
go lid.productId()
return &lid, nil
}
// Get 获取自增id
func (l *lid) Get() int64 {
return <-l.ch
}
// productId 生产id
func (l *lid) productId() {
l.reset()
for {
if l.min >= l.max {
l.reset()
}
l.min++
l.ch <- l.min
}
}
// reset 不断尝试从数据库获取,直到成功
func (l *lid) reset() {
for {
err := l.getFromDB()
if err == nil {
return
}
time.Sleep(time.Second)
continue
}
}
func (l *lid) getFromDB() error {
var (
max_id int64
step int64
//idModel IdModel
idModel utils.GenerateId
)
businessIdfilter := bson.M{utils.FN.GenerateId.BusinessId: l.businessId}
txErr := Shop.Transaction(context.Background(), func(sctx mongo.SessionContext) (err error) {
err = l.db.FindOneEx(sctx, &idModel, businessIdfilter)
if err != nil {
if err == mongo.ErrNoDocuments {
idModel.MaxId = 10000
_, err = l.db.InsertOne(sctx,
bson.M{
utils.FN.GenerateId.BusinessId: l.businessId,
utils.FN.GenerateId.MaxId: 0,
utils.FN.GenerateId.Step: 10,
utils.FN.GenerateId.Desc: "id自增器",
utils.FN.GenerateId.CreateAt: time.Now(),
utils.FN.GenerateId.UpdateAt: time.Now()})
if err != nil {
return
}
} else {
return
}
}
max_id = idModel.MaxId
step = idModel.Step
_, err = l.db.UpdateOne(sctx, businessIdfilter, bson.M{"$set": bson.M{utils.FN.GenerateId.MaxId: max_id + step}})
if err != nil {
return
}
l.min = max_id
l.max = max_id + step
return
})
return txErr
}