Initial commit
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
package channelpackage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/common/stdLog"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
func Init(ctx context.Context) {
|
||||
// 获取数据库表
|
||||
db = mongos.New(mongos.MgoManager, CollChannelPackage)
|
||||
|
||||
// 初始化索引
|
||||
indexes := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: FN.ChannelPackage.AppId, Value: 1},
|
||||
{Key: FN.ChannelPackage.Channel, Value: 1},
|
||||
{Key: FN.ChannelPackage.Version, Value: 1},
|
||||
{Key: FN.ChannelPackage.FileName, Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: FN.ChannelPackage.AppId, Value: 1},
|
||||
{Key: FN.ChannelPackage.Channel, Value: 1},
|
||||
{Key: FN.ChannelPackage.Version, Value: 1},
|
||||
{Key: FN.ChannelPackage.FileName, Value: 1},
|
||||
{Key: FN.ChannelPackage.Status, Value: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := db.CreateIndex(ctx, indexes); err != nil {
|
||||
panic(fmt.Sprintf("Model %s InitIndex error %+v", CollChannelPackage, err))
|
||||
}
|
||||
}
|
||||
|
||||
// InsertOneChannelPackage 插入一个应用
|
||||
func InsertOneChannelPackage(ctx context.Context, ChannelPackage *ChannelPackage) *stdLog.SrvErr {
|
||||
if _, err := db.InsertOne(ctx, ChannelPackage); err != nil {
|
||||
log.Warn("media:InsertOneChannelPackage db.InsertOne failed", log.E(err))
|
||||
return stdLog.New(stdLog.InsertDataError, "", "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DelOneChannelPackage 删除一个应用tag
|
||||
func DelOneChannelPackage(ctx context.Context, filter bson.M) (
|
||||
int64, *stdLog.SrvErr) {
|
||||
count, err := db.DeleteOne(ctx, filter)
|
||||
if err != nil {
|
||||
log.Warn("application:DelOneChannelPackage db.DeleteOne failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return 0, stdLog.New(stdLog.DelDataError, "", "")
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// UpdateOneChannelPackage 更新一个应用
|
||||
func UpdateOneChannelPackage(ctx context.Context, filter bson.M, update bson.M) *stdLog.SrvErr {
|
||||
result, err := db.UpdateOne(ctx, filter, update)
|
||||
if err != nil {
|
||||
log.Warn("application:UpdateOneChannelPackage db.UpdateOne failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return stdLog.New(stdLog.UpdateDataError, "", "")
|
||||
}
|
||||
if result.MatchedCount != 1 {
|
||||
log.Warn("application:UpdateOneChannelPackage db.UpdateOne failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return stdLog.New(stdLog.DataNotExist, "", "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CountChannelPackages 统计应用数量
|
||||
func CountChannelPackages(ctx context.Context, filter bson.M) (
|
||||
int64, *stdLog.SrvErr) {
|
||||
count, err := db.Count(ctx, filter)
|
||||
if err != nil {
|
||||
log.Warn("media:CountChannelPackages db.Count failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return 0, stdLog.New(stdLog.QueryDataError, "", "")
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// FindOneChannelPackage 查找一个应用
|
||||
func FindOneChannelPackage(ctx context.Context, filter bson.M) (
|
||||
*ChannelPackage, *stdLog.SrvErr) {
|
||||
var ChannelPackage ChannelPackage
|
||||
if err := db.FindOneEx(
|
||||
ctx, &ChannelPackage, filter); err != nil {
|
||||
if err != mongo.ErrNoDocuments {
|
||||
log.Info("media:FindOneChannelPackage db.FindOne failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return nil, stdLog.New(stdLog.QueryDataError, "", "")
|
||||
}
|
||||
return nil, stdLog.New(stdLog.DataNotExist, "", "")
|
||||
}
|
||||
return &ChannelPackage, nil
|
||||
}
|
||||
|
||||
// FindManyChannelPackage 查找一批应用
|
||||
func FindManyChannelPackage(ctx context.Context, filter bson.M,
|
||||
opts ...*options.FindOptions) (ChannelPackageList, *stdLog.SrvErr) {
|
||||
data := make(ChannelPackageList, 0)
|
||||
if err := db.Find(ctx, &data, filter, opts...); err != nil {
|
||||
log.Warn("application:FindManyChannelPackage db.Find failed",
|
||||
log.E(err), log.Any("filter", filter))
|
||||
return nil, stdLog.New(stdLog.QueryDataError, "", "")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package channelpackage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"stat/common/stdLog"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (c *ChannelPackage) IncDownCount(ctx context.Context) *stdLog.SrvErr {
|
||||
update := bson.M{
|
||||
"$inc": bson.M{
|
||||
FN.ChannelPackage.DownCount: 1,
|
||||
},
|
||||
"$set": bson.M{
|
||||
FN.ChannelPackage.DownLatest: time.Now(),
|
||||
},
|
||||
}
|
||||
return UpdateOneChannelPackage(ctx, bson.M{FN.ChannelPackage.Id: c.Id}, update)
|
||||
}
|
||||
|
||||
func (c *ChannelPackage) GetRandomLink(domains []string) string {
|
||||
if len(domains) > 0 {
|
||||
base := domains[rand.Intn(len(domains))]
|
||||
link, _ := url.JoinPath(base, c.UrlPath)
|
||||
return link
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *ChannelPackage) GetAllLink(domains []string) []string {
|
||||
if len(domains) > 0 {
|
||||
list := make([]string, 0)
|
||||
for _, domain := range domains {
|
||||
link, _ := url.JoinPath(domain, c.UrlPath)
|
||||
list = append(list, link)
|
||||
}
|
||||
return list
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (c *ChannelPackage) CanMake(force bool) (bool, time.Duration, string) {
|
||||
// 先判断锁定时间(强制生成不可破锁)
|
||||
duration := ApkLockTimeDuration - time.Since(c.LockTime)
|
||||
if duration > 0 {
|
||||
return false, duration, fmt.Sprintf("记录锁定")
|
||||
}
|
||||
if force {
|
||||
return true, 0, "强制生成"
|
||||
}
|
||||
if c.Status == ChanApkStatusSuccess {
|
||||
// 已成功的记录
|
||||
return false, duration, "已经生成成功过,无需重新生成"
|
||||
} else if c.Status == ChanApkStatusMaking {
|
||||
// 判断超时的记录
|
||||
current := time.Now().Sub(c.GenTime)
|
||||
diff := ApkNoResponseDuration - current
|
||||
if diff <= 0 {
|
||||
duration := time.Duration(math.Pow(3, float64(c.GenCount))) * time.Minute
|
||||
if current > duration {
|
||||
return true, -1, "可以生成"
|
||||
} else {
|
||||
return false, duration - current, "未达到可以再次生成的时间"
|
||||
}
|
||||
} else {
|
||||
return false, diff, "正在生成中"
|
||||
}
|
||||
} else {
|
||||
// 判断失败的记录
|
||||
duration := time.Duration(math.Pow(3, float64(c.GenCount))) * time.Minute
|
||||
current := time.Now().Sub(c.GenTime)
|
||||
if current > duration {
|
||||
return true, -1, "上次生成失败已超时,现在可以重新生成"
|
||||
} else {
|
||||
return false, duration - current, "上次生成失败,重新生成的时间未到"
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
package channelpackage
|
||||
|
||||
type TagChannelPackage struct {
|
||||
AppId string
|
||||
Channel string
|
||||
CreatedAt string
|
||||
Desc string
|
||||
Reason string
|
||||
FileName string
|
||||
GenCount string
|
||||
GenError string
|
||||
GenTime string
|
||||
Id string
|
||||
Status string
|
||||
UpdatedAt string
|
||||
UrlPath string
|
||||
Version string
|
||||
LockCode string
|
||||
LockTime string
|
||||
DownCount string
|
||||
DownLatest string
|
||||
CheckLink string
|
||||
}
|
||||
|
||||
var FN struct {
|
||||
ChannelPackage TagChannelPackage
|
||||
}
|
||||
|
||||
var TN struct {
|
||||
ChannelPackage string
|
||||
}
|
||||
|
||||
func init() {
|
||||
FN.ChannelPackage.AppId = "appId"
|
||||
FN.ChannelPackage.Channel = "channel"
|
||||
FN.ChannelPackage.CreatedAt = "createdAt"
|
||||
FN.ChannelPackage.Desc = "desc"
|
||||
FN.ChannelPackage.Reason = "reason"
|
||||
FN.ChannelPackage.FileName = "fileName"
|
||||
FN.ChannelPackage.GenCount = "genCount"
|
||||
FN.ChannelPackage.GenError = "genError"
|
||||
FN.ChannelPackage.GenTime = "genTime"
|
||||
FN.ChannelPackage.Id = "_id"
|
||||
FN.ChannelPackage.Status = "status"
|
||||
FN.ChannelPackage.UpdatedAt = "updatedAt"
|
||||
FN.ChannelPackage.UrlPath = "urlPath"
|
||||
FN.ChannelPackage.Version = "version"
|
||||
FN.ChannelPackage.LockCode = "lockCode"
|
||||
FN.ChannelPackage.LockTime = "lockTime"
|
||||
FN.ChannelPackage.CheckLink = "checkLink"
|
||||
FN.ChannelPackage.DownCount = "downCount"
|
||||
FN.ChannelPackage.DownLatest = "downLatest"
|
||||
TN.ChannelPackage = "channel_package"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package channelpackage
|
||||
|
||||
import (
|
||||
"stat/common/mongos"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
const CollChannelPackage = "channel_package"
|
||||
|
||||
var db *mongos.MongoTool
|
||||
|
||||
type ChanApkStatus int64
|
||||
|
||||
const (
|
||||
ChanApkStatusUnknown ChanApkStatus = iota
|
||||
ChanApkStatusMaking // 正在生成
|
||||
ChanApkStatusSuccess // 生成成功
|
||||
ChanApkStatusFailure // 生成失败
|
||||
)
|
||||
|
||||
const (
|
||||
ApkLockTimeDuration = 30 * time.Minute // 记录锁定时间
|
||||
ApkNoResponseDuration = 60 * time.Minute // 生成时无响应间隔
|
||||
ApkCheckLinkDuration = 10 * time.Minute // 生成时无响应间隔
|
||||
ApkGenerateParallelMax = int64(5) // 并行生成APK的最大任务数
|
||||
)
|
||||
|
||||
// 渠道包
|
||||
// @table:channel_package
|
||||
type ChannelPackage struct {
|
||||
Id primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
||||
AppId int32 `json:"appId" bson:"appId"` // appId
|
||||
Channel string `json:"channel" bson:"channel"` // 渠道
|
||||
Version string `bson:"version" json:"version"` // 版本号
|
||||
FileName string `json:"fileName" bson:"fileName"` // 包文件名
|
||||
UrlPath string `json:"urlPath" bson:"urlPath"` // UrlPath
|
||||
Status ChanApkStatus `json:"status" bson:"status"` // 状态
|
||||
Desc string `bson:"desc" json:"desc"` // 版本描述
|
||||
GenError string `bson:"genError" json:"genError"` // 生成错误
|
||||
GenCount int64 `bson:"genCount" json:"genCount"` // 生成次数
|
||||
GenTime time.Time `bson:"genTime" json:"genTime"` // 生成时间
|
||||
Reason string `bson:"reason" json:"reason"` // 生成原因
|
||||
LockCode int64 `bson:"lockCode" json:"lockCode"` // 更新锁码
|
||||
LockTime time.Time `bson:"lockTime" json:"lockTime"` // 锁定时间
|
||||
DownCount int64 `bson:"downCount" json:"downCount"` // 下载次数
|
||||
DownLatest time.Time `bson:"downLatest" json:"downLatest"` // 最后下载时间
|
||||
CheckLink time.Time `bson:"checkLink" json:"checkLink"` // 检查链接
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type ChannelPackageList []*ChannelPackage
|
||||
|
||||
type ChannelPackageUpdate struct {
|
||||
AppId *int32 `json:"appId" bson:"appId"` // appId
|
||||
Channel *string `json:"channel" bson:"channel"` // 渠道
|
||||
Version *string `bson:"version" json:"version"` // 版本号
|
||||
FileName *string `json:"fileName" bson:"fileName"` // 包文件名
|
||||
UrlPath *string `json:"urlPath" bson:"urlPath"` // UrlPath
|
||||
Status *int64 `json:"status" bson:"status"` // 状态
|
||||
Desc *string `bson:"desc" json:"desc"` // 版本描述
|
||||
GenError *string `bson:"genError" json:"genError"` // 生成错误
|
||||
GenCount *int64 `bson:"genCount" json:"genCount"` // 生成次数
|
||||
GenTime *time.Time `bson:"genTime" json:"genTime"` // 生成时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
|
||||
}
|
||||
Reference in New Issue
Block a user