[feat] delayStart and autoReset #718
This commit is contained in:
@@ -35,6 +35,14 @@ type Client struct {
|
|||||||
Up int64 `json:"up" form:"up"`
|
Up int64 `json:"up" form:"up"`
|
||||||
Desc string `json:"desc" form:"desc"`
|
Desc string `json:"desc" form:"desc"`
|
||||||
Group string `json:"group" form:"group"`
|
Group string `json:"group" form:"group"`
|
||||||
|
|
||||||
|
// Delay start and periodic reset
|
||||||
|
DelayStart bool `json:"delayStart" form:"delayStart" gorm:"default:false;not null"`
|
||||||
|
AutoReset bool `json:"autoReset" form:"autoReset" gorm:"default:false;not null"`
|
||||||
|
ResetDays int `json:"resetDays" form:"resetDays" gorm:"default:0;not null"`
|
||||||
|
NextReset int64 `json:"nextReset" form:"nextReset" gorm:"default:0;not null"`
|
||||||
|
TotalUp int64 `json:"totalUp" form:"totalUp" gorm:"default:0;not null"`
|
||||||
|
TotalDown int64 `json:"totalDown" form:"totalDown" gorm:"default:0;not null"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stats struct {
|
type Stats struct {
|
||||||
|
|||||||
+100
-5
@@ -38,7 +38,9 @@ func (s *ClientService) getById(id string) (*[]model.Client, error) {
|
|||||||
func (s *ClientService) GetAll() (*[]model.Client, error) {
|
func (s *ClientService) GetAll() (*[]model.Client, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var clients []model.Client
|
var clients []model.Client
|
||||||
err := db.Model(model.Client{}).Select("`id`, `enable`, `name`, `desc`, `group`, `inbounds`, `up`, `down`, `volume`, `expiry`").Scan(&clients).Error
|
err := db.Model(model.Client{}).
|
||||||
|
Select("`id`, `enable`, `name`, `desc`, `group`, `inbounds`, `up`, `down`, `volume`, `expiry`").
|
||||||
|
Scan(&clients).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -369,24 +371,34 @@ func (s *ClientService) DepleteClients() ([]uint, error) {
|
|||||||
var users []string
|
var users []string
|
||||||
var inboundIds []uint
|
var inboundIds []uint
|
||||||
|
|
||||||
now := time.Now().Unix()
|
dt := time.Now().Unix()
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
|
|
||||||
tx := db.Begin()
|
tx := db.Begin()
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
_, err1 := db.Raw("PRAGMA wal_checkpoint(FULL)").Rows()
|
||||||
|
if err1 != nil {
|
||||||
|
logger.Error("Error checkpointing WAL: ", err1.Error())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = tx.Model(model.Client{}).Where("enable = true AND ((volume >0 AND up+down > volume) OR (expiry > 0 AND expiry < ?))", now).Scan(&clients).Error
|
// Reset clients
|
||||||
|
inboundIds, err = s.ResetClients(tx, dt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deplete clients
|
||||||
|
err = tx.Model(model.Client{}).Where("enable = true AND ((volume >0 AND up+down > volume) OR (expiry > 0 AND expiry < ?))", dt).Scan(&clients).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dt := time.Now().Unix()
|
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
logger.Debug("Client ", client.Name, " is going to be disabled")
|
logger.Debug("Client ", client.Name, " is going to be disabled")
|
||||||
users = append(users, client.Name)
|
users = append(users, client.Name)
|
||||||
@@ -405,7 +417,7 @@ func (s *ClientService) DepleteClients() ([]uint, error) {
|
|||||||
|
|
||||||
// Save changes
|
// Save changes
|
||||||
if len(changes) > 0 {
|
if len(changes) > 0 {
|
||||||
err = tx.Model(model.Client{}).Where("enable = true AND ((volume >0 AND up+down > volume) OR (expiry > 0 AND expiry < ?))", now).Update("enable", false).Error
|
err = tx.Model(model.Client{}).Where("enable = true AND ((volume >0 AND up+down > volume) OR (expiry > 0 AND expiry < ?))", dt).Update("enable", false).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -419,6 +431,89 @@ func (s *ClientService) DepleteClients() ([]uint, error) {
|
|||||||
return inboundIds, nil
|
return inboundIds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ClientService) ResetClients(tx *gorm.DB, dt int64) ([]uint, error) {
|
||||||
|
var err error
|
||||||
|
var resetClients, allClients []*model.Client
|
||||||
|
var changes []model.Changes
|
||||||
|
var inboundIds []uint
|
||||||
|
// Set delay start without periodic reset
|
||||||
|
err = tx.Model(model.Client{}).
|
||||||
|
Where("enable = true AND delay_start = true AND auto_reset = false AND (Up + Down) > 0").Find(&resetClients).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, client := range resetClients {
|
||||||
|
client.Expiry = dt + (int64(client.ResetDays) * 86400)
|
||||||
|
client.DelayStart = false
|
||||||
|
changes = append(changes, model.Changes{
|
||||||
|
DateTime: dt,
|
||||||
|
Actor: "ResetJob",
|
||||||
|
Key: "clients",
|
||||||
|
Action: "reset",
|
||||||
|
Obj: json.RawMessage("\"" + client.Name + "\""),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
allClients = append(allClients, resetClients...)
|
||||||
|
|
||||||
|
// Set delay start with periodic reset
|
||||||
|
err = tx.Model(model.Client{}).
|
||||||
|
Where("enable = true AND delay_start = true AND auto_reset = true AND (Up + Down) > 0").Find(&resetClients).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, client := range resetClients {
|
||||||
|
client.NextReset = dt + (int64(client.ResetDays) * 86400)
|
||||||
|
client.DelayStart = false
|
||||||
|
changes = append(changes, model.Changes{
|
||||||
|
DateTime: dt,
|
||||||
|
Actor: "ResetJob",
|
||||||
|
Key: "clients",
|
||||||
|
Action: "reset",
|
||||||
|
Obj: json.RawMessage("\"" + client.Name + "\""),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
allClients = append(allClients, resetClients...)
|
||||||
|
|
||||||
|
// Set periodic reset
|
||||||
|
err = tx.Model(model.Client{}).
|
||||||
|
Where("delay_start = false AND auto_reset = true AND next_reset < ?", dt).Find(&resetClients).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, client := range resetClients {
|
||||||
|
client.NextReset = dt + (int64(client.ResetDays) * 86400)
|
||||||
|
client.TotalUp += client.Up
|
||||||
|
client.TotalDown += client.Down
|
||||||
|
client.Up = 0
|
||||||
|
client.Down = 0
|
||||||
|
if !client.Enable {
|
||||||
|
client.Enable = true
|
||||||
|
var clientInboundIds []uint
|
||||||
|
json.Unmarshal(client.Inbounds, &clientInboundIds)
|
||||||
|
inboundIds = common.UnionUintArray(inboundIds, clientInboundIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allClients = append(allClients, resetClients...)
|
||||||
|
|
||||||
|
// Save clients
|
||||||
|
if len(allClients) > 0 {
|
||||||
|
err = tx.Save(allClients).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save changes
|
||||||
|
if len(changes) > 0 {
|
||||||
|
err = tx.Model(model.Changes{}).Create(&changes).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
LastUpdate = dt
|
||||||
|
}
|
||||||
|
return inboundIds, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ClientService) findInboundsChanges(tx *gorm.DB, client *model.Client, fillOmitted bool) ([]uint, error) {
|
func (s *ClientService) findInboundsChanges(tx *gorm.DB, client *model.Client, fillOmitted bool) ([]uint, error) {
|
||||||
var err error
|
var err error
|
||||||
var oldClient model.Client
|
var oldClient model.Client
|
||||||
|
|||||||
+2
-2
@@ -268,8 +268,8 @@ func (s *ServerService) GetDatabaseInfo() map[string]int64 {
|
|||||||
db.Model(&model.Outbound{}).Count(&outboundsCount)
|
db.Model(&model.Outbound{}).Count(&outboundsCount)
|
||||||
db.Model(&model.Service{}).Count(&servicesCount)
|
db.Model(&model.Service{}).Count(&servicesCount)
|
||||||
db.Model(&model.Endpoint{}).Count(&endpointsCount)
|
db.Model(&model.Endpoint{}).Count(&endpointsCount)
|
||||||
db.Model(&model.Client{}).Select("COALESCE(SUM(up),0)").Scan(&clientUp)
|
db.Model(&model.Client{}).Select("COALESCE(SUM(up+total_up),0)").Scan(&clientUp)
|
||||||
db.Model(&model.Client{}).Select("COALESCE(SUM(down),0)").Scan(&clientDown)
|
db.Model(&model.Client{}).Select("COALESCE(SUM(down+total_down),0)").Scan(&clientDown)
|
||||||
|
|
||||||
info["clients"] = clientsCount
|
info["clients"] = clientsCount
|
||||||
info["inbounds"] = inboundsCount
|
info["inbounds"] = inboundsCount
|
||||||
|
|||||||
Reference in New Issue
Block a user