文件存储-定时同步租户文件存储容量信息接口优化
This commit is contained in:
@@ -7,9 +7,17 @@ import (
|
|||||||
"oss/model/entity"
|
"oss/model/entity"
|
||||||
)
|
)
|
||||||
|
|
||||||
var File = &file{}
|
var File = &file{
|
||||||
|
NoCache: false,
|
||||||
|
}
|
||||||
|
|
||||||
type file struct{}
|
type file struct {
|
||||||
|
NoCache bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *file) SetNoCache() {
|
||||||
|
File.NoCache = true
|
||||||
|
}
|
||||||
|
|
||||||
// Insert 插入
|
// Insert 插入
|
||||||
func (d *file) Insert(ctx context.Context, entity *entity.File) (err error) {
|
func (d *file) Insert(ctx context.Context, entity *entity.File) (err error) {
|
||||||
|
|||||||
@@ -9,9 +9,17 @@ import (
|
|||||||
"oss/model/entity"
|
"oss/model/entity"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TenantOssTotal = &tenantOssTotal{}
|
var TenantOssTotal = &tenantOssTotal{
|
||||||
|
NoCache: false,
|
||||||
|
}
|
||||||
|
|
||||||
type tenantOssTotal struct{}
|
type tenantOssTotal struct {
|
||||||
|
NoCache bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *tenantOssTotal) SetNoCache() {
|
||||||
|
TenantOssTotal.NoCache = true
|
||||||
|
}
|
||||||
|
|
||||||
// Insert 插入
|
// Insert 插入
|
||||||
func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err error) {
|
func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err error) {
|
||||||
@@ -20,12 +28,12 @@ func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveOrUpdate 增加或更新
|
// SaveOrUpdate 增加或更新
|
||||||
func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, filterData []*entity.TenantOssTotal, updateData []*entity.TenantOssTotal) (err error) {
|
func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*entity.TenantOssTotal) (err error) {
|
||||||
if !g.IsEmpty(updateData) {
|
if !g.IsEmpty(updateData) {
|
||||||
var filter, update []bson.M
|
var filter, update []bson.M
|
||||||
for i, v := range filterData {
|
for _, v := range updateData {
|
||||||
filter = append(filter, bson.M{"tenantId": v.TenantId})
|
filter = append(filter, bson.M{"tenantId": v.TenantId})
|
||||||
update = append(update, bson.M{"$set": bson.M{"usedOssSize": updateData[i].UsedOssSize, "totalOssSize": updateData[i].TotalOssSize}})
|
update = append(update, bson.M{"$set": bson.M{"usedOssSize": v.UsedOssSize, "totalOssSize": v.TotalOssSize}})
|
||||||
}
|
}
|
||||||
_, err = mongo.SaveOrUpdate(ctx, filter, update, consts.TenantOssTotalCollection)
|
_, err = mongo.SaveOrUpdate(ctx, filter, update, consts.TenantOssTotalCollection)
|
||||||
}
|
}
|
||||||
@@ -35,6 +43,6 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, filterData []*entity.
|
|||||||
func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, tenantId string) (e *entity.TenantOssTotal, err error) {
|
func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, tenantId string) (e *entity.TenantOssTotal, err error) {
|
||||||
filter := bson.M{"tenantId": tenantId}
|
filter := bson.M{"tenantId": tenantId}
|
||||||
e = &entity.TenantOssTotal{}
|
e = &entity.TenantOssTotal{}
|
||||||
err = mongo.FindOne(ctx, filter, e, consts.TenantOssTotalCollection)
|
err = mongo.FindOne(ctx, d.NoCache, filter, e, consts.TenantOssTotalCollection)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type File struct {
|
|||||||
do.MongoBaseDO `bson:",inline"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
do.MongoBaseDO `bson:",inline"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
||||||
// 基础信息
|
// 基础信息
|
||||||
FileURL string `bson:"fileURL" json:"fileURL"` // 图URL
|
FileURL string `bson:"fileURL" json:"fileURL"` // 图URL
|
||||||
FileSize int64 `bson:"fileSize" json:"fileSize"`
|
FileSize byte `bson:"fileSize" json:"fileSize"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CollectionName 存储集合名称
|
// CollectionName 存储集合名称
|
||||||
|
|||||||
@@ -22,79 +22,68 @@ type file struct{}
|
|||||||
var File = new(file)
|
var File = new(file)
|
||||||
|
|
||||||
func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
|
func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
|
||||||
tenantId := ""
|
fileSize := gconv.Byte(req.File.Size)
|
||||||
fileSize := req.File.Size
|
|
||||||
totalFileSize := int64(0)
|
totalFileSize := int64(0)
|
||||||
// 获取租户id
|
// 获取租户id
|
||||||
user, err := mongo.GetTenantInfo(ctx)
|
user, err := mongo.GetTenantInfo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tenantId := gconv.String(user.TenantId)
|
||||||
// 获取redis-租户存储容量总数key
|
// 获取redis-租户存储容量总数key
|
||||||
tenantOssTotalKey := fmt.Sprintf(consts.TenantOssTotalKey, gconv.String(user.TenantId))
|
tenantOssTotalKey := fmt.Sprintf(consts.TenantOssTotalKey, gconv.String(user.TenantId))
|
||||||
// 获取redis-租户存储-锁key
|
// 获取redis-租户存储-锁key
|
||||||
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
|
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
|
||||||
i := 0
|
|
||||||
LOCK:
|
success, err := redis.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
|
||||||
if ok, err := redis.RedisClient.SetNX(ctx, fileLockKey, fileSize); !ok || err != nil {
|
// 获取redis-租户存储容量总数
|
||||||
// 获取锁失败,需要重试
|
get, err := redis.RedisClient.Get(ctx, tenantOssTotalKey)
|
||||||
if i < 5 {
|
|
||||||
i++
|
|
||||||
time.Sleep(5 * time.Millisecond)
|
|
||||||
goto LOCK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 设置redis-租户存储-锁key超时时间1分钟
|
|
||||||
err = redis.RedisClient.SetEX(ctx, fileLockKey, fileSize, gconv.Int64(time.Minute*1))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// 获取redis-租户存储容量总数
|
|
||||||
get, err := redis.RedisClient.Get(ctx, tenantOssTotalKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tenantOssTotalEntity := &entity.TenantOssTotal{}
|
|
||||||
if g.IsEmpty(get) {
|
|
||||||
//查询数据库-获取租户存储容量总数
|
|
||||||
getByTenantIdReq := &dto.GetByTenantIdReq{
|
|
||||||
TenantId: gconv.String(user.TenantId),
|
|
||||||
}
|
|
||||||
tenantOssTotal, err := TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if g.IsEmpty(tenantOssTotal) {
|
tenantOssTotalEntity := &entity.TenantOssTotal{}
|
||||||
tenantOssTotalEntity.TenantId = user.TenantId
|
if g.IsEmpty(get) {
|
||||||
tenantOssTotalEntity.UsedOssSize = int64(0)
|
//查询数据库-获取租户存储容量总数
|
||||||
tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int64()
|
getByTenantIdReq := &dto.GetByTenantIdReq{
|
||||||
|
TenantId: gconv.String(user.TenantId),
|
||||||
|
}
|
||||||
|
tenantOssTotal, err := TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if tenantOssTotal.Id.IsZero() {
|
||||||
|
tenantOssTotalEntity.TenantId = user.TenantId
|
||||||
|
tenantOssTotalEntity.UsedOssSize = int64(0)
|
||||||
|
tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int64()
|
||||||
|
} else {
|
||||||
|
tenantOssTotalEntity = tenantOssTotal.TenantOssTotal
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tenantOssTotalEntity = tenantOssTotal.TenantOssTotal
|
// 反序列化-redis获取租户存储容量总数
|
||||||
|
err = gconv.Struct(get, tenantOssTotalEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
tenantId = gconv.String(tenantOssTotalEntity.TenantId)
|
||||||
// 反序列化-redis获取租户存储容量总数
|
fileSize = gconv.Byte(tenantOssTotalEntity.UsedOssSize) + fileSize
|
||||||
err = gconv.Struct(get, tenantOssTotalEntity)
|
totalFileSize = tenantOssTotalEntity.TotalOssSize
|
||||||
|
// 设置redis-租户存储容量总数
|
||||||
|
tenantOssTotalKeyMap := map[string]interface{}{"tenantId": tenantId, "UsedOssSize": fileSize, "TotalOssSize": totalFileSize}
|
||||||
|
// 修改redis-租户存储容量总数 超时时间10分钟
|
||||||
|
err = redis.RedisClient.SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
if fileSize > gconv.Byte(totalFileSize) {
|
||||||
tenantId = gconv.String(tenantOssTotalEntity.TenantId)
|
return gerror.New("存储服务内存不足")
|
||||||
fileSize = tenantOssTotalEntity.UsedOssSize + fileSize
|
}
|
||||||
totalFileSize = tenantOssTotalEntity.TotalOssSize
|
return nil
|
||||||
// 设置redis-租户存储容量总数
|
})
|
||||||
tenantOssTotalKeyMap := map[string]interface{}{"tenantId": tenantId, "UsedOssSize": fileSize, "TotalOssSize": totalFileSize}
|
|
||||||
// 修改redis-租户存储容量总数 超时时间10分钟
|
|
||||||
err = redis.RedisClient.SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if fileSize < totalFileSize {
|
if !success {
|
||||||
// 删除redis-租户存储-锁key
|
|
||||||
_, err = redis.RedisClient.Del(ctx, fileLockKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, gerror.New("存储服务内存不足")
|
return nil, gerror.New("存储服务内存不足")
|
||||||
}
|
}
|
||||||
// 上传图片
|
// 上传图片
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"gitee.com/red-future---jilin-g/common/redis"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"oss/consts"
|
"oss/consts"
|
||||||
@@ -27,12 +28,11 @@ func (s *tenantOssTotal) GetOneByTenantId(ctx context.Context, req *dto.GetByTen
|
|||||||
|
|
||||||
func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
|
func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
|
||||||
// 使用 Keys 取出所有key
|
// 使用 Keys 取出所有key
|
||||||
keys, err := g.Redis().Keys(ctx, consts.OssTotalKey)
|
keys, err := redis.RedisClient.Keys(ctx, consts.OssTotalKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateData := make([]*entity.TenantOssTotal, 0)
|
updateData := make([]*entity.TenantOssTotal, 0)
|
||||||
filterData := make([]*entity.TenantOssTotal, 0)
|
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
get, err := g.Redis().Get(ctx, key)
|
get, err := g.Redis().Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -44,13 +44,10 @@ func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
updateData = append(updateData, e)
|
updateData = append(updateData, e)
|
||||||
totalOssSize := &entity.TenantOssTotal{}
|
|
||||||
totalOssSize.TenantId = e.TenantId
|
|
||||||
filterData = append(filterData, totalOssSize)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// 更新数据库
|
// 更新数据库
|
||||||
err = dao.TenantOssTotal.SaveOrUpdate(ctx, filterData, updateData)
|
err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user