mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-12-15 23:26:35 +08:00
增加刷新、预热缓存任务管理
This commit is contained in:
338
internal/rpc/services/service_http_cache_task.go
Normal file
338
internal/rpc/services/service_http_cache_task.go
Normal file
@@ -0,0 +1,338 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// HTTPCacheTaskService 缓存任务管理
|
||||
type HTTPCacheTaskService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
// CreateHTTPCacheTask 创建任务
|
||||
func (this *HTTPCacheTaskService) CreateHTTPCacheTask(ctx context.Context, req *pb.CreateHTTPCacheTaskRequest) (*pb.CreateHTTPCacheTaskResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查操作类型
|
||||
if req.Type != models.HTTPCacheTaskTypePurge && req.Type != models.HTTPCacheTaskTypeFetch {
|
||||
return nil, errors.New("invalid type '" + req.Type + "'")
|
||||
}
|
||||
|
||||
// 检查Key数量
|
||||
var clusterId int64
|
||||
if userId > 0 {
|
||||
// TODO 限制当日刷新总条数(配额)
|
||||
if len(req.Keys) > models.MaxKeysPerTask {
|
||||
return nil, errors.New("too many keys (current:" + types.String(len(req.Keys)) + ", max:" + types.String(models.MaxKeysPerTask) + ")")
|
||||
}
|
||||
|
||||
clusterId, err = models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 创建任务
|
||||
taskId, err := models.SharedHTTPCacheTaskDAO.CreateTask(tx, userId, req.Type, req.KeyType, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var countKeys = 0
|
||||
var domainMap = map[string]*models.Server{} // domain name => *Server
|
||||
for _, key := range req.Keys {
|
||||
if len(key) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取域名
|
||||
var domain = utils.ParseDomainFromKey(key)
|
||||
if len(domain) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查询所在集群
|
||||
server, ok := domainMap[domain]
|
||||
if !ok {
|
||||
server, err = models.SharedServerDAO.FindEnabledServerWithDomain(tx, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if server == nil {
|
||||
continue
|
||||
}
|
||||
domainMap[domain] = server
|
||||
}
|
||||
|
||||
// 检查用户
|
||||
if userId > 0 {
|
||||
if int64(server.UserId) != userId {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var serverClusterId = int64(server.ClusterId)
|
||||
if serverClusterId == 0 {
|
||||
if clusterId > 0 {
|
||||
serverClusterId = clusterId
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
_, err = models.SharedHTTPCacheTaskKeyDAO.CreateKey(tx, taskId, key, req.Type, req.KeyType, serverClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
countKeys++
|
||||
}
|
||||
|
||||
if countKeys == 0 {
|
||||
// 如果没有有效的Key,则直接完成
|
||||
err = models.SharedHTTPCacheTaskDAO.UpdateTaskStatus(tx, taskId, true, true)
|
||||
} else {
|
||||
err = models.SharedHTTPCacheTaskDAO.UpdateTaskReady(tx, taskId)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateHTTPCacheTaskResponse{
|
||||
HttpCacheTaskId: taskId,
|
||||
CountKeys: int64(countKeys),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CountHTTPCacheTasks 计算任务数量
|
||||
func (this *HTTPCacheTaskService) CountHTTPCacheTasks(ctx context.Context, req *pb.CountHTTPCacheTasksRequest) (*pb.RPCCountResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
count, err := models.SharedHTTPCacheTaskDAO.CountTasks(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// CountDoingHTTPCacheTasks 计算正在执行的任务数量
|
||||
func (this *HTTPCacheTaskService) CountDoingHTTPCacheTasks(ctx context.Context, req *pb.CountDoingHTTPCacheTasksRequest) (*pb.RPCCountResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
count, err := models.SharedHTTPCacheTaskDAO.CountDoingTasks(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListHTTPCacheTasks 列出单页任务
|
||||
func (this *HTTPCacheTaskService) ListHTTPCacheTasks(ctx context.Context, req *pb.ListHTTPCacheTasksRequest) (*pb.ListHTTPCacheTasksResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
tasks, err := models.SharedHTTPCacheTaskDAO.ListTasks(tx, userId, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbTasks = []*pb.HTTPCacheTask{}
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
for _, task := range tasks {
|
||||
var taskId = int64(task.Id)
|
||||
|
||||
// 查询所属用户
|
||||
var pbUser = &pb.User{}
|
||||
if task.UserId > 0 {
|
||||
var taskUserId = int64(task.UserId)
|
||||
if taskUserId > 0 {
|
||||
taskUser, err := models.SharedUserDAO.FindEnabledUser(tx, taskUserId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if taskUser == nil {
|
||||
// 找不到用户就删除
|
||||
err = models.SharedHTTPCacheTaskDAO.DisableHTTPCacheTask(tx, taskUserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(taskUser.Id),
|
||||
Username: taskUser.Username,
|
||||
Fullname: taskUser.Fullname,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pbTasks = append(pbTasks, &pb.HTTPCacheTask{
|
||||
Id: taskId,
|
||||
UserId: int64(task.UserId),
|
||||
Type: task.Type,
|
||||
KeyType: task.KeyType,
|
||||
CreatedAt: int64(task.CreatedAt),
|
||||
DoneAt: int64(task.DoneAt),
|
||||
IsDone: task.IsDone,
|
||||
IsOk: task.IsOk,
|
||||
Description: task.Description,
|
||||
User: pbUser,
|
||||
HttpCacheTaskKeys: nil,
|
||||
})
|
||||
}
|
||||
return &pb.ListHTTPCacheTasksResponse{
|
||||
HttpCacheTasks: pbTasks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindEnabledHTTPCacheTask 查找单个任务
|
||||
func (this *HTTPCacheTaskService) FindEnabledHTTPCacheTask(ctx context.Context, req *pb.FindEnabledHTTPCacheTaskRequest) (*pb.FindEnabledHTTPCacheTaskResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPCacheTaskDAO.CheckUserTask(tx, userId, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
task, err := models.SharedHTTPCacheTaskDAO.FindEnabledHTTPCacheTask(tx, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if task == nil {
|
||||
return &pb.FindEnabledHTTPCacheTaskResponse{HttpCacheTask: nil}, nil
|
||||
}
|
||||
|
||||
// 查询所属用户
|
||||
var pbUser = &pb.User{}
|
||||
if task.UserId > 0 {
|
||||
var taskUserId = int64(task.UserId)
|
||||
if taskUserId > 0 {
|
||||
taskUser, err := models.SharedUserDAO.FindEnabledUser(tx, taskUserId, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if taskUser == nil {
|
||||
// 找不到用户就删除
|
||||
err = models.SharedHTTPCacheTaskDAO.DisableHTTPCacheTask(tx, taskUserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(taskUser.Id),
|
||||
Username: taskUser.Username,
|
||||
Fullname: taskUser.Fullname,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keys
|
||||
keys, err := models.SharedHTTPCacheTaskKeyDAO.FindAllTaskKeys(tx, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbKeys = []*pb.HTTPCacheTaskKey{}
|
||||
for _, key := range keys {
|
||||
pbKeys = append(pbKeys, &pb.HTTPCacheTaskKey{
|
||||
Id: int64(key.Id),
|
||||
TaskId: int64(key.TaskId),
|
||||
Key: key.Key,
|
||||
KeyType: key.KeyType,
|
||||
IsDone: key.IsDone,
|
||||
ErrorsJSON: key.Errors,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindEnabledHTTPCacheTaskResponse{
|
||||
HttpCacheTask: &pb.HTTPCacheTask{
|
||||
Id: int64(task.Id),
|
||||
UserId: int64(task.UserId),
|
||||
Type: task.Type,
|
||||
KeyType: task.KeyType,
|
||||
CreatedAt: int64(task.CreatedAt),
|
||||
DoneAt: int64(task.DoneAt),
|
||||
IsDone: task.IsDone,
|
||||
IsOk: task.IsOk,
|
||||
User: pbUser,
|
||||
HttpCacheTaskKeys: pbKeys,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteHTTPCacheTask 删除任务
|
||||
func (this *HTTPCacheTaskService) DeleteHTTPCacheTask(ctx context.Context, req *pb.DeleteHTTPCacheTaskRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPCacheTaskDAO.CheckUserTask(tx, userId, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPCacheTaskDAO.DisableHTTPCacheTask(tx, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// ResetHTTPCacheTask 重置任务状态
|
||||
// 只允许管理员重置,用于调试
|
||||
func (this *HTTPCacheTaskService) ResetHTTPCacheTask(ctx context.Context, req *pb.ResetHTTPCacheTaskRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 重置任务
|
||||
err = models.SharedHTTPCacheTaskDAO.ResetTask(tx, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 重置任务下的Key
|
||||
err = models.SharedHTTPCacheTaskKeyDAO.ResetCacheKeysWithTaskId(tx, req.HttpCacheTaskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
180
internal/rpc/services/service_http_cache_task_key.go
Normal file
180
internal/rpc/services/service_http_cache_task_key.go
Normal file
@@ -0,0 +1,180 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// HTTPCacheTaskKeyService 缓存任务Key管理
|
||||
type HTTPCacheTaskKeyService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
// ValidateHTTPCacheTaskKeys 校验缓存Key
|
||||
func (this *HTTPCacheTaskKeyService) ValidateHTTPCacheTaskKeys(ctx context.Context, req *pb.ValidateHTTPCacheTaskKeysRequest) (*pb.ValidateHTTPCacheTaskKeysResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
|
||||
// 检查Key数量
|
||||
var clusterId int64
|
||||
if userId > 0 {
|
||||
// TODO 限制当日刷新总条数(配额)
|
||||
if len(req.Keys) > models.MaxKeysPerTask {
|
||||
return nil, errors.New("too many keys (current:" + types.String(len(req.Keys)) + ", max:" + types.String(models.MaxKeysPerTask) + ")")
|
||||
}
|
||||
|
||||
clusterId, err = models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var pbFailResults = []*pb.ValidateHTTPCacheTaskKeysResponse_FailKey{}
|
||||
var domainMap = map[string]*models.Server{} // domain name => *Server
|
||||
for _, key := range req.Keys {
|
||||
if len(key) == 0 {
|
||||
pbFailResults = append(pbFailResults, &pb.ValidateHTTPCacheTaskKeysResponse_FailKey{
|
||||
Key: key,
|
||||
ReasonCode: "requireKey",
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取域名
|
||||
var domain = utils.ParseDomainFromKey(key)
|
||||
if len(domain) == 0 {
|
||||
pbFailResults = append(pbFailResults, &pb.ValidateHTTPCacheTaskKeysResponse_FailKey{
|
||||
Key: key,
|
||||
ReasonCode: "requireDomain",
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 查询所在集群
|
||||
server, ok := domainMap[domain]
|
||||
if !ok {
|
||||
server, err = models.SharedServerDAO.FindEnabledServerWithDomain(tx, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if server == nil {
|
||||
pbFailResults = append(pbFailResults, &pb.ValidateHTTPCacheTaskKeysResponse_FailKey{
|
||||
Key: key,
|
||||
ReasonCode: "requireServer",
|
||||
})
|
||||
continue
|
||||
}
|
||||
domainMap[domain] = server
|
||||
}
|
||||
|
||||
// 检查用户
|
||||
if userId > 0 {
|
||||
if int64(server.UserId) != userId {
|
||||
pbFailResults = append(pbFailResults, &pb.ValidateHTTPCacheTaskKeysResponse_FailKey{
|
||||
Key: key,
|
||||
ReasonCode: "requireUser",
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var serverClusterId = int64(server.ClusterId)
|
||||
if serverClusterId == 0 {
|
||||
if clusterId > 0 {
|
||||
serverClusterId = clusterId
|
||||
} else {
|
||||
pbFailResults = append(pbFailResults, &pb.ValidateHTTPCacheTaskKeysResponse_FailKey{
|
||||
Key: key,
|
||||
ReasonCode: "requireClusterId",
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.ValidateHTTPCacheTaskKeysResponse{FailKeys: pbFailResults}, nil
|
||||
}
|
||||
|
||||
// FindDoingHTTPCacheTaskKeys 查找需要执行的Key
|
||||
func (this *HTTPCacheTaskKeyService) FindDoingHTTPCacheTaskKeys(ctx context.Context, req *pb.FindDoingHTTPCacheTaskKeysRequest) (*pb.FindDoingHTTPCacheTaskKeysResponse, error) {
|
||||
nodeId, err := this.ValidateNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Size <= 0 {
|
||||
req.Size = 100
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
keys, err := models.SharedHTTPCacheTaskKeyDAO.FindDoingTaskKeys(tx, nodeId, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbKeys = []*pb.HTTPCacheTaskKey{}
|
||||
for _, key := range keys {
|
||||
pbKeys = append(pbKeys, &pb.HTTPCacheTaskKey{
|
||||
Id: int64(key.Id),
|
||||
TaskId: int64(key.TaskId),
|
||||
Key: key.Key,
|
||||
Type: key.Type,
|
||||
KeyType: key.KeyType,
|
||||
NodeClusterId: int64(key.ClusterId),
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindDoingHTTPCacheTaskKeysResponse{HttpCacheTaskKeys: pbKeys}, nil
|
||||
}
|
||||
|
||||
// UpdateHTTPCacheTaskKeysStatus 更新一组Key状态
|
||||
func (this *HTTPCacheTaskKeyService) UpdateHTTPCacheTaskKeysStatus(ctx context.Context, req *pb.UpdateHTTPCacheTaskKeysStatusRequest) (*pb.RPCSuccess, error) {
|
||||
nodeId, err := this.ValidateNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
|
||||
var nodesJSONMap = map[int64][]byte{} // clusterId => nodesJSON
|
||||
|
||||
for _, result := range req.KeyResults {
|
||||
// 集群Id
|
||||
var clusterId = result.NodeClusterId
|
||||
nodesJSON, ok := nodesJSONMap[clusterId]
|
||||
if !ok {
|
||||
nodeIdsInCluster, err := models.SharedNodeDAO.FindEnabledAndOnNodeIdsWithClusterId(tx, clusterId, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var nodeMap = map[int64]bool{}
|
||||
for _, nodeIdInCluster := range nodeIdsInCluster {
|
||||
nodeMap[nodeIdInCluster] = true
|
||||
}
|
||||
nodesJSON, err = json.Marshal(nodeMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodesJSONMap[clusterId] = nodesJSON
|
||||
}
|
||||
|
||||
err = models.SharedHTTPCacheTaskKeyDAO.UpdateKeyStatus(tx, result.Id, nodeId, result.Error, nodesJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
23
internal/rpc/services/service_http_cache_task_test.go
Normal file
23
internal/rpc/services/service_http_cache_task_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHTTPCacheTaskService_CountHTTPCacheTasks(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
|
||||
var service = &HTTPCacheTaskService{}
|
||||
a.IsTrue(service.parseDomain("aaa") == "aaa")
|
||||
a.IsTrue(service.parseDomain("AAA") == "aaa")
|
||||
a.IsTrue(service.parseDomain("a.b-c.com") == "a.b-c.com")
|
||||
a.IsTrue(service.parseDomain("a.b-c.com/hello/world") == "a.b-c.com")
|
||||
a.IsTrue(service.parseDomain("https://a.b-c.com") == "a.b-c.com")
|
||||
a.IsTrue(service.parseDomain("http://a.b-c.com/hello/world") == "a.b-c.com")
|
||||
a.IsTrue(service.parseDomain("http://a.B-c.com/hello/world") == "a.b-c.com")
|
||||
a.IsTrue(service.parseDomain("http:/aaaa.com") == "http")
|
||||
a.IsTrue(service.parseDomain("北京") == "")
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
@@ -154,7 +153,7 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
||||
}
|
||||
}
|
||||
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UnixJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, string(req.IncludeNodesJSON), string(req.ExcludeNodesJSON), req.ServerGroupIds, req.UserPlanId)
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UnixJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, req.IncludeNodesJSON, req.ExcludeNodesJSON, req.ServerGroupIds, req.UserPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1710,79 +1709,88 @@ func (this *ServerService) PurgeServerCache(ctx context.Context, req *pb.PurgeSe
|
||||
}
|
||||
}
|
||||
|
||||
if len(req.Domains) == 0 {
|
||||
return nil, errors.New("'domains' field is required")
|
||||
}
|
||||
|
||||
if len(req.Keys) == 0 && len(req.Prefixes) == 0 {
|
||||
return &pb.PurgeServerCacheResponse{IsOk: true}, nil
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
var purgeResponse = &pb.PurgeServerCacheResponse{}
|
||||
|
||||
for _, domain := range req.Domains {
|
||||
servers, err := models.SharedServerDAO.FindAllEnabledServersWithDomain(tx, domain)
|
||||
var tx = this.NullTx()
|
||||
|
||||
var taskType = "purge"
|
||||
|
||||
var tasks = []*pb.CreateHTTPCacheTaskRequest{}
|
||||
if len(req.Keys) > 0 {
|
||||
tasks = append(tasks, &pb.CreateHTTPCacheTaskRequest{
|
||||
Type: taskType,
|
||||
KeyType: "key",
|
||||
Keys: req.Keys,
|
||||
})
|
||||
}
|
||||
if len(req.Prefixes) > 0 {
|
||||
tasks = append(tasks, &pb.CreateHTTPCacheTaskRequest{
|
||||
Type: taskType,
|
||||
KeyType: "prefix",
|
||||
Keys: req.Prefixes,
|
||||
})
|
||||
}
|
||||
|
||||
var domainMap = map[string]*models.Server{} // domain name => *Server
|
||||
|
||||
for _, pbTask := range tasks {
|
||||
// 创建任务
|
||||
taskId, err := models.SharedHTTPCacheTaskDAO.CreateTask(tx, 0, pbTask.Type, pbTask.KeyType, "调用PURGE API")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, server := range servers {
|
||||
clusterId := int64(server.ClusterId)
|
||||
if clusterId > 0 {
|
||||
nodeIds, err := models.SharedNodeDAO.FindAllEnabledNodeIdsWithClusterId(tx, clusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var countKeys = 0
|
||||
|
||||
cachePolicyId, err := models.SharedNodeClusterDAO.FindClusterHTTPCachePolicyId(tx, clusterId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cachePolicyId == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cachePolicy, err := models.SharedHTTPCachePolicyDAO.ComposeCachePolicy(tx, cachePolicyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cachePolicy == nil {
|
||||
continue
|
||||
}
|
||||
cachePolicyJSON, err := json.Marshal(cachePolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, nodeId := range nodeIds {
|
||||
msg := &messageconfigs.PurgeCacheMessage{
|
||||
CachePolicyJSON: cachePolicyJSON,
|
||||
}
|
||||
if len(req.Prefixes) > 0 {
|
||||
msg.Type = messageconfigs.PurgeCacheMessageTypeDir
|
||||
msg.Keys = req.Prefixes
|
||||
} else {
|
||||
msg.Type = messageconfigs.PurgeCacheMessageTypeFile
|
||||
msg.Keys = req.Keys
|
||||
}
|
||||
msgJSON, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := SendCommandToNode(nodeId, NextCommandRequestId(), messageconfigs.MessageCodePurgeCache, msgJSON, 10, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !resp.IsOk {
|
||||
purgeResponse.IsOk = false
|
||||
purgeResponse.Message = resp.Message
|
||||
return purgeResponse, nil
|
||||
}
|
||||
}
|
||||
for _, key := range req.Keys {
|
||||
if len(key) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取域名
|
||||
var domain = utils.ParseDomainFromKey(key)
|
||||
if len(domain) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查询所在集群
|
||||
server, ok := domainMap[domain]
|
||||
if !ok {
|
||||
server, err = models.SharedServerDAO.FindEnabledServerWithDomain(tx, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if server == nil {
|
||||
continue
|
||||
}
|
||||
domainMap[domain] = server
|
||||
}
|
||||
|
||||
var serverClusterId = int64(server.ClusterId)
|
||||
if serverClusterId == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = models.SharedHTTPCacheTaskKeyDAO.CreateKey(tx, taskId, key, pbTask.Type, pbTask.KeyType, serverClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
countKeys++
|
||||
}
|
||||
|
||||
if countKeys == 0 {
|
||||
// 如果没有有效的Key,则直接完成
|
||||
err = models.SharedHTTPCacheTaskDAO.UpdateTaskStatus(tx, taskId, true, true)
|
||||
} else {
|
||||
err = models.SharedHTTPCacheTaskDAO.UpdateTaskReady(tx, taskId)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ func TestServerService_UploadServerHTTPRequestStat(t *testing.T) {
|
||||
Month: timeutil.Format("Ym"),
|
||||
RegionCities: []*pb.UploadServerHTTPRequestStatRequest_RegionCity{
|
||||
{
|
||||
ServerId: 1,
|
||||
CountryName: "中国",
|
||||
ProvinceName: "安徽省",
|
||||
CityName: "阜阳市",
|
||||
Count: 1,
|
||||
ServerId: 1,
|
||||
CountryName: "中国",
|
||||
ProvinceName: "安徽省",
|
||||
CityName: "阜阳市",
|
||||
CountRequests: 1,
|
||||
},
|
||||
},
|
||||
RegionProviders: []*pb.UploadServerHTTPRequestStatRequest_RegionProvider{
|
||||
|
||||
Reference in New Issue
Block a user