完善通道删除与定时失效功能
This commit is contained in:
140
cmd/fill/main.go
140
cmd/fill/main.go
@@ -5,8 +5,9 @@ import (
|
||||
"platform/pkg/env"
|
||||
"platform/pkg/logs"
|
||||
"platform/pkg/orm"
|
||||
"platform/web/models"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@@ -16,59 +17,96 @@ func main() {
|
||||
logs.Init()
|
||||
orm.Init()
|
||||
|
||||
q.User.
|
||||
Select(
|
||||
q.User.Phone).
|
||||
Create(&models.User{
|
||||
Phone: "12312341234"})
|
||||
err := q.Q.Transaction(func(tx *q.Query) error {
|
||||
q.User.
|
||||
Select(q.User.Phone).
|
||||
Save(&m.User{
|
||||
Phone: "12312341234",
|
||||
})
|
||||
var user, _ = q.User.First()
|
||||
|
||||
q.Proxy.
|
||||
Select(
|
||||
q.Proxy.Version,
|
||||
q.Proxy.Name,
|
||||
q.Proxy.Host,
|
||||
q.Proxy.Type).
|
||||
Create(&models.Proxy{
|
||||
Version: 1,
|
||||
Name: "7a17e8b4-cdc3-4500-bf16-4a665991a7f6",
|
||||
Host: "110.40.82.248",
|
||||
Type: 1})
|
||||
q.Resource.
|
||||
Select(q.Resource.UserID, q.Resource.Active).
|
||||
Create(&m.Resource{
|
||||
UserID: user.ID,
|
||||
Active: true,
|
||||
})
|
||||
var resource, _ = q.Resource.First()
|
||||
|
||||
q.Node.
|
||||
Select(
|
||||
q.Node.Version,
|
||||
q.Node.Name,
|
||||
q.Node.Host,
|
||||
q.Node.Isp,
|
||||
q.Node.Prov,
|
||||
q.Node.City,
|
||||
q.Node.Status).
|
||||
Create(&models.Node{
|
||||
Version: 1,
|
||||
Name: "test-node",
|
||||
Host: "123",
|
||||
Isp: "test-isp",
|
||||
Prov: "test-prov",
|
||||
City: "test-city",
|
||||
Status: 1})
|
||||
q.ResourcePss.
|
||||
Select(
|
||||
q.ResourcePss.ResourceID,
|
||||
q.ResourcePss.Live,
|
||||
q.ResourcePss.Type,
|
||||
q.ResourcePss.Expire,
|
||||
q.ResourcePss.DailyLimit,
|
||||
).
|
||||
Create(&m.ResourcePss{
|
||||
ResourceID: resource.ID,
|
||||
Live: 180,
|
||||
Type: 1,
|
||||
Expire: time.Now().Add(24 * time.Hour * 1000),
|
||||
DailyLimit: 300000,
|
||||
})
|
||||
|
||||
var secret, _ = bcrypt.GenerateFromPassword([]byte("test"), bcrypt.DefaultCost)
|
||||
q.Client.
|
||||
Select(
|
||||
q.Client.ClientID,
|
||||
q.Client.ClientSecret,
|
||||
q.Client.GrantClient,
|
||||
q.Client.GrantRefresh,
|
||||
q.Client.Spec,
|
||||
q.Client.Name).
|
||||
Create(&models.Client{
|
||||
ClientID: "test",
|
||||
ClientSecret: string(secret),
|
||||
GrantClient: true,
|
||||
GrantRefresh: true,
|
||||
Spec: 0,
|
||||
Name: "默认客户端",
|
||||
})
|
||||
q.Proxy.
|
||||
Select(q.Proxy.Version, q.Proxy.Name, q.Proxy.Host, q.Proxy.Type, q.Proxy.Secret).
|
||||
Create(&m.Proxy{
|
||||
Version: 1,
|
||||
Name: "7a17e8b4-cdc3-4500-bf16-4a665991a7f6",
|
||||
Host: "110.40.82.248",
|
||||
Type: 1,
|
||||
Secret: "api:123456",
|
||||
})
|
||||
|
||||
q.Node.
|
||||
Select(
|
||||
q.Node.Version,
|
||||
q.Node.Name,
|
||||
q.Node.Host,
|
||||
q.Node.Isp,
|
||||
q.Node.Prov,
|
||||
q.Node.City,
|
||||
q.Node.Status).
|
||||
Create(&m.Node{
|
||||
Version: 1,
|
||||
Name: "test-node",
|
||||
Host: "123",
|
||||
Isp: "test-isp",
|
||||
Prov: "test-prov",
|
||||
City: "test-city",
|
||||
Status: 1})
|
||||
|
||||
var testSecret, _ = bcrypt.GenerateFromPassword([]byte("test"), bcrypt.DefaultCost)
|
||||
var tasksSecret, _ = bcrypt.GenerateFromPassword([]byte("tasks"), bcrypt.DefaultCost)
|
||||
q.Client.
|
||||
Select(
|
||||
q.Client.ClientID,
|
||||
q.Client.ClientSecret,
|
||||
q.Client.GrantClient,
|
||||
q.Client.GrantRefresh,
|
||||
q.Client.Spec,
|
||||
q.Client.Name).
|
||||
Create(&m.Client{
|
||||
ClientID: "test",
|
||||
ClientSecret: string(testSecret),
|
||||
GrantClient: true,
|
||||
GrantRefresh: true,
|
||||
Spec: 0,
|
||||
Name: "默认客户端",
|
||||
}, &m.Client{
|
||||
ClientID: "tasks",
|
||||
ClientSecret: string(tasksSecret),
|
||||
GrantClient: true,
|
||||
GrantRefresh: true,
|
||||
Spec: 0,
|
||||
Name: "异步任务处理服务",
|
||||
})
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
slog.Info("✔ Data inserted successfully")
|
||||
}
|
||||
|
||||
@@ -1,33 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"platform/pkg/env"
|
||||
"platform/pkg/logs"
|
||||
"platform/pkg/orm"
|
||||
"platform/web/models"
|
||||
q "platform/web/queries"
|
||||
)
|
||||
import "math"
|
||||
|
||||
type ResourceInfo struct {
|
||||
data models.Resource
|
||||
pss models.ResourcePss
|
||||
}
|
||||
var b62Set = make(map[string]struct{})
|
||||
var b64Set = make(map[string]struct{})
|
||||
|
||||
func main() {
|
||||
|
||||
env.Init()
|
||||
logs.Init()
|
||||
orm.Init()
|
||||
|
||||
var resource = new(ResourceInfo)
|
||||
data := q.Resource.As("data")
|
||||
pss := q.ResourcePss.As("pss")
|
||||
_ = data.Debug().Scopes(orm.Alias(data)).
|
||||
Select(data.ALL, pss.ALL).
|
||||
LeftJoin(q.ResourcePss.As("pss"), pss.ResourceID.EqCol(data.ID)).
|
||||
Where(data.ID.Eq(1)).
|
||||
Scan(&resource)
|
||||
|
||||
fmt.Printf("%+v\n", resource)
|
||||
println(int(math.Ceil(100 * 1.1)))
|
||||
println(int(math.Ceil(float64(100) * 1.1)))
|
||||
}
|
||||
|
||||
@@ -2,12 +2,18 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"platform/pkg/env"
|
||||
"platform/pkg/logs"
|
||||
"platform/pkg/orm"
|
||||
"platform/pkg/rds"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
@@ -17,27 +23,51 @@ func main() {
|
||||
Start()
|
||||
}
|
||||
|
||||
var taskList = make(map[string]func(ctx context.Context, curr time.Time) error)
|
||||
|
||||
func Start() {
|
||||
ctx := context.Background()
|
||||
|
||||
env.Init()
|
||||
logs.Init()
|
||||
rds.Init()
|
||||
orm.Init()
|
||||
|
||||
taskList["stopChannels"] = stopChannels
|
||||
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
// 互斥锁确保同一时间只有一个协程运行
|
||||
// 如果之前的 tick 操作未完成,则跳过当前 tick
|
||||
var mutex = &sync.Mutex{}
|
||||
for curr := range ticker.C {
|
||||
err := process(ctx, curr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if mutex.TryLock() {
|
||||
err := process(ctx, curr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mutex.Unlock()
|
||||
} else {
|
||||
slog.Warn("skip tick", slog.String("tick", curr.Format("2006-01-02 15:04:05")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func process(ctx context.Context, curr time.Time) error {
|
||||
|
||||
// todo 异步化
|
||||
for name, task := range taskList {
|
||||
err := task(ctx, curr)
|
||||
if err != nil {
|
||||
slog.Error("task failed", slog.String("task", name), slog.String("error", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func stopChannels(ctx context.Context, curr time.Time) error {
|
||||
|
||||
// 获取并删除
|
||||
script := redis.NewScript(`
|
||||
local result = redis.call('ZRANGEBYSCORE', KEYS[1], 0, ARGV[1])
|
||||
@@ -47,21 +77,64 @@ func process(ctx context.Context, curr time.Time) error {
|
||||
return result
|
||||
`)
|
||||
|
||||
// 计算时间范围
|
||||
// 执行脚本
|
||||
result, err := script.Run(ctx, rds.Client, []string{"tasks:session"}, curr.Unix()).Result()
|
||||
result, err := script.Run(ctx, rds.Client, []string{"tasks:channel"}, curr.Unix()).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理结果
|
||||
list, ok := result.([]string)
|
||||
list, ok := result.([]any)
|
||||
if !ok {
|
||||
return errors.New("failed to convert result to []string")
|
||||
}
|
||||
for _, item := range list {
|
||||
// 从数据库删除授权信息
|
||||
slog.Debug(item)
|
||||
var ids = make([]int, len(list))
|
||||
for i, item := range list {
|
||||
idStr, ok := item.(string)
|
||||
if !ok {
|
||||
slog.Debug(reflect.TypeOf(item).String())
|
||||
return errors.New("failed to convert item to string")
|
||||
}
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ids[i] = id
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var body = map[string]any{
|
||||
"by_ids": ids,
|
||||
}
|
||||
bodyStr, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(
|
||||
http.MethodPost,
|
||||
"http://localhost:8080/api/channel/remove", // todo 环境变量获取服务地址
|
||||
strings.NewReader(string(bodyStr)),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.SetBasicAuth("tasks", "tasks")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return errors.New("failed to stop channels: " + string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user