Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
63a8c769
Unverified
Commit
63a8c769
authored
Mar 06, 2026
by
Wesley Liddick
Committed by
GitHub
Mar 06, 2026
Browse files
Merge pull request #798 from touwaeriol/feature/account-load-factor
feat: add account load_factor for scheduling load calculation
parents
f355a68b
c87e6526
Changes
30
Hide whitespace changes
Inline
Side-by-side
backend/ent/account.go
View file @
63a8c769
...
...
@@ -41,6 +41,8 @@ type Account struct {
ProxyID
*
int64
`json:"proxy_id,omitempty"`
// Concurrency holds the value of the "concurrency" field.
Concurrency
int
`json:"concurrency,omitempty"`
// LoadFactor holds the value of the "load_factor" field.
LoadFactor
*
int
`json:"load_factor,omitempty"`
// Priority holds the value of the "priority" field.
Priority
int
`json:"priority,omitempty"`
// RateMultiplier holds the value of the "rate_multiplier" field.
...
...
@@ -143,7 +145,7 @@ func (*Account) scanValues(columns []string) ([]any, error) {
values
[
i
]
=
new
(
sql
.
NullBool
)
case
account
.
FieldRateMultiplier
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
case
account
.
FieldID
,
account
.
FieldProxyID
,
account
.
FieldConcurrency
,
account
.
FieldPriority
:
case
account
.
FieldID
,
account
.
FieldProxyID
,
account
.
FieldConcurrency
,
account
.
FieldLoadFactor
,
account
.
FieldPriority
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
account
.
FieldName
,
account
.
FieldNotes
,
account
.
FieldPlatform
,
account
.
FieldType
,
account
.
FieldStatus
,
account
.
FieldErrorMessage
,
account
.
FieldTempUnschedulableReason
,
account
.
FieldSessionWindowStatus
:
values
[
i
]
=
new
(
sql
.
NullString
)
...
...
@@ -243,6 +245,13 @@ func (_m *Account) assignValues(columns []string, values []any) error {
}
else
if
value
.
Valid
{
_m
.
Concurrency
=
int
(
value
.
Int64
)
}
case
account
.
FieldLoadFactor
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field load_factor"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
LoadFactor
=
new
(
int
)
*
_m
.
LoadFactor
=
int
(
value
.
Int64
)
}
case
account
.
FieldPriority
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field priority"
,
values
[
i
])
...
...
@@ -445,6 +454,11 @@ func (_m *Account) String() string {
builder
.
WriteString
(
"concurrency="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Concurrency
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
LoadFactor
;
v
!=
nil
{
builder
.
WriteString
(
"load_factor="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
*
v
))
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"priority="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Priority
))
builder
.
WriteString
(
", "
)
...
...
backend/ent/account/account.go
View file @
63a8c769
...
...
@@ -37,6 +37,8 @@ const (
FieldProxyID
=
"proxy_id"
// FieldConcurrency holds the string denoting the concurrency field in the database.
FieldConcurrency
=
"concurrency"
// FieldLoadFactor holds the string denoting the load_factor field in the database.
FieldLoadFactor
=
"load_factor"
// FieldPriority holds the string denoting the priority field in the database.
FieldPriority
=
"priority"
// FieldRateMultiplier holds the string denoting the rate_multiplier field in the database.
...
...
@@ -121,6 +123,7 @@ var Columns = []string{
FieldExtra
,
FieldProxyID
,
FieldConcurrency
,
FieldLoadFactor
,
FieldPriority
,
FieldRateMultiplier
,
FieldStatus
,
...
...
@@ -250,6 +253,11 @@ func ByConcurrency(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldConcurrency
,
opts
...
)
.
ToFunc
()
}
// ByLoadFactor orders the results by the load_factor field.
func
ByLoadFactor
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldLoadFactor
,
opts
...
)
.
ToFunc
()
}
// ByPriority orders the results by the priority field.
func
ByPriority
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldPriority
,
opts
...
)
.
ToFunc
()
...
...
backend/ent/account/where.go
View file @
63a8c769
...
...
@@ -100,6 +100,11 @@ func Concurrency(v int) predicate.Account {
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldConcurrency
,
v
))
}
// LoadFactor applies equality check predicate on the "load_factor" field. It's identical to LoadFactorEQ.
func
LoadFactor
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldLoadFactor
,
v
))
}
// Priority applies equality check predicate on the "priority" field. It's identical to PriorityEQ.
func
Priority
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldPriority
,
v
))
...
...
@@ -650,6 +655,56 @@ func ConcurrencyLTE(v int) predicate.Account {
return
predicate
.
Account
(
sql
.
FieldLTE
(
FieldConcurrency
,
v
))
}
// LoadFactorEQ applies the EQ predicate on the "load_factor" field.
func
LoadFactorEQ
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldLoadFactor
,
v
))
}
// LoadFactorNEQ applies the NEQ predicate on the "load_factor" field.
func
LoadFactorNEQ
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNEQ
(
FieldLoadFactor
,
v
))
}
// LoadFactorIn applies the In predicate on the "load_factor" field.
func
LoadFactorIn
(
vs
...
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldIn
(
FieldLoadFactor
,
vs
...
))
}
// LoadFactorNotIn applies the NotIn predicate on the "load_factor" field.
func
LoadFactorNotIn
(
vs
...
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNotIn
(
FieldLoadFactor
,
vs
...
))
}
// LoadFactorGT applies the GT predicate on the "load_factor" field.
func
LoadFactorGT
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGT
(
FieldLoadFactor
,
v
))
}
// LoadFactorGTE applies the GTE predicate on the "load_factor" field.
func
LoadFactorGTE
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGTE
(
FieldLoadFactor
,
v
))
}
// LoadFactorLT applies the LT predicate on the "load_factor" field.
func
LoadFactorLT
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLT
(
FieldLoadFactor
,
v
))
}
// LoadFactorLTE applies the LTE predicate on the "load_factor" field.
func
LoadFactorLTE
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLTE
(
FieldLoadFactor
,
v
))
}
// LoadFactorIsNil applies the IsNil predicate on the "load_factor" field.
func
LoadFactorIsNil
()
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldIsNull
(
FieldLoadFactor
))
}
// LoadFactorNotNil applies the NotNil predicate on the "load_factor" field.
func
LoadFactorNotNil
()
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNotNull
(
FieldLoadFactor
))
}
// PriorityEQ applies the EQ predicate on the "priority" field.
func
PriorityEQ
(
v
int
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldPriority
,
v
))
...
...
backend/ent/account_create.go
View file @
63a8c769
...
...
@@ -139,6 +139,20 @@ func (_c *AccountCreate) SetNillableConcurrency(v *int) *AccountCreate {
return
_c
}
// SetLoadFactor sets the "load_factor" field.
func
(
_c
*
AccountCreate
)
SetLoadFactor
(
v
int
)
*
AccountCreate
{
_c
.
mutation
.
SetLoadFactor
(
v
)
return
_c
}
// SetNillableLoadFactor sets the "load_factor" field if the given value is not nil.
func
(
_c
*
AccountCreate
)
SetNillableLoadFactor
(
v
*
int
)
*
AccountCreate
{
if
v
!=
nil
{
_c
.
SetLoadFactor
(
*
v
)
}
return
_c
}
// SetPriority sets the "priority" field.
func
(
_c
*
AccountCreate
)
SetPriority
(
v
int
)
*
AccountCreate
{
_c
.
mutation
.
SetPriority
(
v
)
...
...
@@ -623,6 +637,10 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
account
.
FieldConcurrency
,
field
.
TypeInt
,
value
)
_node
.
Concurrency
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
LoadFactor
();
ok
{
_spec
.
SetField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
,
value
)
_node
.
LoadFactor
=
&
value
}
if
value
,
ok
:=
_c
.
mutation
.
Priority
();
ok
{
_spec
.
SetField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
_node
.
Priority
=
value
...
...
@@ -936,6 +954,30 @@ func (u *AccountUpsert) AddConcurrency(v int) *AccountUpsert {
return
u
}
// SetLoadFactor sets the "load_factor" field.
func
(
u
*
AccountUpsert
)
SetLoadFactor
(
v
int
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldLoadFactor
,
v
)
return
u
}
// UpdateLoadFactor sets the "load_factor" field to the value that was provided on create.
func
(
u
*
AccountUpsert
)
UpdateLoadFactor
()
*
AccountUpsert
{
u
.
SetExcluded
(
account
.
FieldLoadFactor
)
return
u
}
// AddLoadFactor adds v to the "load_factor" field.
func
(
u
*
AccountUpsert
)
AddLoadFactor
(
v
int
)
*
AccountUpsert
{
u
.
Add
(
account
.
FieldLoadFactor
,
v
)
return
u
}
// ClearLoadFactor clears the value of the "load_factor" field.
func
(
u
*
AccountUpsert
)
ClearLoadFactor
()
*
AccountUpsert
{
u
.
SetNull
(
account
.
FieldLoadFactor
)
return
u
}
// SetPriority sets the "priority" field.
func
(
u
*
AccountUpsert
)
SetPriority
(
v
int
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldPriority
,
v
)
...
...
@@ -1419,6 +1461,34 @@ func (u *AccountUpsertOne) UpdateConcurrency() *AccountUpsertOne {
})
}
// SetLoadFactor sets the "load_factor" field.
func
(
u
*
AccountUpsertOne
)
SetLoadFactor
(
v
int
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetLoadFactor
(
v
)
})
}
// AddLoadFactor adds v to the "load_factor" field.
func
(
u
*
AccountUpsertOne
)
AddLoadFactor
(
v
int
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
AddLoadFactor
(
v
)
})
}
// UpdateLoadFactor sets the "load_factor" field to the value that was provided on create.
func
(
u
*
AccountUpsertOne
)
UpdateLoadFactor
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateLoadFactor
()
})
}
// ClearLoadFactor clears the value of the "load_factor" field.
func
(
u
*
AccountUpsertOne
)
ClearLoadFactor
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
ClearLoadFactor
()
})
}
// SetPriority sets the "priority" field.
func
(
u
*
AccountUpsertOne
)
SetPriority
(
v
int
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
...
@@ -2113,6 +2183,34 @@ func (u *AccountUpsertBulk) UpdateConcurrency() *AccountUpsertBulk {
})
}
// SetLoadFactor sets the "load_factor" field.
func
(
u
*
AccountUpsertBulk
)
SetLoadFactor
(
v
int
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetLoadFactor
(
v
)
})
}
// AddLoadFactor adds v to the "load_factor" field.
func
(
u
*
AccountUpsertBulk
)
AddLoadFactor
(
v
int
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
AddLoadFactor
(
v
)
})
}
// UpdateLoadFactor sets the "load_factor" field to the value that was provided on create.
func
(
u
*
AccountUpsertBulk
)
UpdateLoadFactor
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateLoadFactor
()
})
}
// ClearLoadFactor clears the value of the "load_factor" field.
func
(
u
*
AccountUpsertBulk
)
ClearLoadFactor
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
ClearLoadFactor
()
})
}
// SetPriority sets the "priority" field.
func
(
u
*
AccountUpsertBulk
)
SetPriority
(
v
int
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
...
backend/ent/account_update.go
View file @
63a8c769
...
...
@@ -172,6 +172,33 @@ func (_u *AccountUpdate) AddConcurrency(v int) *AccountUpdate {
return
_u
}
// SetLoadFactor sets the "load_factor" field.
func
(
_u
*
AccountUpdate
)
SetLoadFactor
(
v
int
)
*
AccountUpdate
{
_u
.
mutation
.
ResetLoadFactor
()
_u
.
mutation
.
SetLoadFactor
(
v
)
return
_u
}
// SetNillableLoadFactor sets the "load_factor" field if the given value is not nil.
func
(
_u
*
AccountUpdate
)
SetNillableLoadFactor
(
v
*
int
)
*
AccountUpdate
{
if
v
!=
nil
{
_u
.
SetLoadFactor
(
*
v
)
}
return
_u
}
// AddLoadFactor adds value to the "load_factor" field.
func
(
_u
*
AccountUpdate
)
AddLoadFactor
(
v
int
)
*
AccountUpdate
{
_u
.
mutation
.
AddLoadFactor
(
v
)
return
_u
}
// ClearLoadFactor clears the value of the "load_factor" field.
func
(
_u
*
AccountUpdate
)
ClearLoadFactor
()
*
AccountUpdate
{
_u
.
mutation
.
ClearLoadFactor
()
return
_u
}
// SetPriority sets the "priority" field.
func
(
_u
*
AccountUpdate
)
SetPriority
(
v
int
)
*
AccountUpdate
{
_u
.
mutation
.
ResetPriority
()
...
...
@@ -684,6 +711,15 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
value
,
ok
:=
_u
.
mutation
.
AddedConcurrency
();
ok
{
_spec
.
AddField
(
account
.
FieldConcurrency
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
LoadFactor
();
ok
{
_spec
.
SetField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedLoadFactor
();
ok
{
_spec
.
AddField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
,
value
)
}
if
_u
.
mutation
.
LoadFactorCleared
()
{
_spec
.
ClearField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
)
}
if
value
,
ok
:=
_u
.
mutation
.
Priority
();
ok
{
_spec
.
SetField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
}
...
...
@@ -1063,6 +1099,33 @@ func (_u *AccountUpdateOne) AddConcurrency(v int) *AccountUpdateOne {
return
_u
}
// SetLoadFactor sets the "load_factor" field.
func
(
_u
*
AccountUpdateOne
)
SetLoadFactor
(
v
int
)
*
AccountUpdateOne
{
_u
.
mutation
.
ResetLoadFactor
()
_u
.
mutation
.
SetLoadFactor
(
v
)
return
_u
}
// SetNillableLoadFactor sets the "load_factor" field if the given value is not nil.
func
(
_u
*
AccountUpdateOne
)
SetNillableLoadFactor
(
v
*
int
)
*
AccountUpdateOne
{
if
v
!=
nil
{
_u
.
SetLoadFactor
(
*
v
)
}
return
_u
}
// AddLoadFactor adds value to the "load_factor" field.
func
(
_u
*
AccountUpdateOne
)
AddLoadFactor
(
v
int
)
*
AccountUpdateOne
{
_u
.
mutation
.
AddLoadFactor
(
v
)
return
_u
}
// ClearLoadFactor clears the value of the "load_factor" field.
func
(
_u
*
AccountUpdateOne
)
ClearLoadFactor
()
*
AccountUpdateOne
{
_u
.
mutation
.
ClearLoadFactor
()
return
_u
}
// SetPriority sets the "priority" field.
func
(
_u
*
AccountUpdateOne
)
SetPriority
(
v
int
)
*
AccountUpdateOne
{
_u
.
mutation
.
ResetPriority
()
...
...
@@ -1605,6 +1668,15 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
if
value
,
ok
:=
_u
.
mutation
.
AddedConcurrency
();
ok
{
_spec
.
AddField
(
account
.
FieldConcurrency
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
LoadFactor
();
ok
{
_spec
.
SetField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedLoadFactor
();
ok
{
_spec
.
AddField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
,
value
)
}
if
_u
.
mutation
.
LoadFactorCleared
()
{
_spec
.
ClearField
(
account
.
FieldLoadFactor
,
field
.
TypeInt
)
}
if
value
,
ok
:=
_u
.
mutation
.
Priority
();
ok
{
_spec
.
SetField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
}
...
...
backend/ent/migrate/schema.go
View file @
63a8c769
...
...
@@ -106,6 +106,7 @@ var (
{
Name
:
"credentials"
,
Type
:
field
.
TypeJSON
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"jsonb"
}},
{
Name
:
"extra"
,
Type
:
field
.
TypeJSON
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"jsonb"
}},
{
Name
:
"concurrency"
,
Type
:
field
.
TypeInt
,
Default
:
3
},
{
Name
:
"load_factor"
,
Type
:
field
.
TypeInt
,
Nullable
:
true
},
{
Name
:
"priority"
,
Type
:
field
.
TypeInt
,
Default
:
50
},
{
Name
:
"rate_multiplier"
,
Type
:
field
.
TypeFloat64
,
Default
:
1
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(10,4)"
}},
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
...
...
@@ -132,7 +133,7 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
Symbol
:
"accounts_proxies_proxy"
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
7
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
8
]},
RefColumns
:
[]
*
schema
.
Column
{
ProxiesColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
},
...
...
@@ -151,52 +152,52 @@ var (
{
Name
:
"account_status"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
3
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
4
]},
},
{
Name
:
"account_proxy_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
7
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
8
]},
},
{
Name
:
"account_priority"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
1
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
2
]},
},
{
Name
:
"account_last_used_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
5
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
6
]},
},
{
Name
:
"account_schedulable"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
8
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
9
]},
},
{
Name
:
"account_rate_limited_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
19
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
20
]},
},
{
Name
:
"account_rate_limit_reset_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
0
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
1
]},
},
{
Name
:
"account_overload_until"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
1
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
2
]},
},
{
Name
:
"account_platform_priority"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
6
],
AccountsColumns
[
1
1
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
6
],
AccountsColumns
[
1
2
]},
},
{
Name
:
"account_priority_status"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
1
],
AccountsColumns
[
1
3
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
2
],
AccountsColumns
[
1
4
]},
},
{
Name
:
"account_deleted_at"
,
...
...
backend/ent/mutation.go
View file @
63a8c769
...
...
@@ -2260,6 +2260,8 @@ type AccountMutation struct {
extra *map[string]interface{}
concurrency *int
addconcurrency *int
load_factor *int
addload_factor *int
priority *int
addpriority *int
rate_multiplier *float64
...
...
@@ -2845,6 +2847,76 @@ func (m *AccountMutation) ResetConcurrency() {
m.addconcurrency = nil
}
// SetLoadFactor sets the "load_factor" field.
func (m *AccountMutation) SetLoadFactor(i int) {
m.load_factor = &i
m.addload_factor = nil
}
// LoadFactor returns the value of the "load_factor" field in the mutation.
func (m *AccountMutation) LoadFactor() (r int, exists bool) {
v := m.load_factor
if v == nil {
return
}
return *v, true
}
// OldLoadFactor returns the old "load_factor" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AccountMutation) OldLoadFactor(ctx context.Context) (v *int, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldLoadFactor is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldLoadFactor requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldLoadFactor: %w", err)
}
return oldValue.LoadFactor, nil
}
// AddLoadFactor adds i to the "load_factor" field.
func (m *AccountMutation) AddLoadFactor(i int) {
if m.addload_factor != nil {
*m.addload_factor += i
} else {
m.addload_factor = &i
}
}
// AddedLoadFactor returns the value that was added to the "load_factor" field in this mutation.
func (m *AccountMutation) AddedLoadFactor() (r int, exists bool) {
v := m.addload_factor
if v == nil {
return
}
return *v, true
}
// ClearLoadFactor clears the value of the "load_factor" field.
func (m *AccountMutation) ClearLoadFactor() {
m.load_factor = nil
m.addload_factor = nil
m.clearedFields[account.FieldLoadFactor] = struct{}{}
}
// LoadFactorCleared returns if the "load_factor" field was cleared in this mutation.
func (m *AccountMutation) LoadFactorCleared() bool {
_, ok := m.clearedFields[account.FieldLoadFactor]
return ok
}
// ResetLoadFactor resets all changes to the "load_factor" field.
func (m *AccountMutation) ResetLoadFactor() {
m.load_factor = nil
m.addload_factor = nil
delete(m.clearedFields, account.FieldLoadFactor)
}
// SetPriority sets the "priority" field.
func (m *AccountMutation) SetPriority(i int) {
m.priority = &i
...
...
@@ -3773,7 +3845,7 @@ func (m *AccountMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *AccountMutation) Fields() []string {
fields := make([]string, 0, 2
7
)
fields := make([]string, 0, 2
8
)
if m.created_at != nil {
fields = append(fields, account.FieldCreatedAt)
}
...
...
@@ -3807,6 +3879,9 @@ func (m *AccountMutation) Fields() []string {
if m.concurrency != nil {
fields = append(fields, account.FieldConcurrency)
}
if m.load_factor != nil {
fields = append(fields, account.FieldLoadFactor)
}
if m.priority != nil {
fields = append(fields, account.FieldPriority)
}
...
...
@@ -3885,6 +3960,8 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
return m.ProxyID()
case account.FieldConcurrency:
return m.Concurrency()
case account.FieldLoadFactor:
return m.LoadFactor()
case account.FieldPriority:
return m.Priority()
case account.FieldRateMultiplier:
...
...
@@ -3948,6 +4025,8 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldProxyID(ctx)
case account.FieldConcurrency:
return m.OldConcurrency(ctx)
case account.FieldLoadFactor:
return m.OldLoadFactor(ctx)
case account.FieldPriority:
return m.OldPriority(ctx)
case account.FieldRateMultiplier:
...
...
@@ -4066,6 +4145,13 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
}
m.SetConcurrency(v)
return nil
case account.FieldLoadFactor:
v, ok := value.(int)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetLoadFactor(v)
return nil
case account.FieldPriority:
v, ok := value.(int)
if !ok {
...
...
@@ -4189,6 +4275,9 @@ func (m *AccountMutation) AddedFields() []string {
if m.addconcurrency != nil {
fields = append(fields, account.FieldConcurrency)
}
if m.addload_factor != nil {
fields = append(fields, account.FieldLoadFactor)
}
if m.addpriority != nil {
fields = append(fields, account.FieldPriority)
}
...
...
@@ -4205,6 +4294,8 @@ func (m *AccountMutation) AddedField(name string) (ent.Value, bool) {
switch name {
case account.FieldConcurrency:
return m.AddedConcurrency()
case account.FieldLoadFactor:
return m.AddedLoadFactor()
case account.FieldPriority:
return m.AddedPriority()
case account.FieldRateMultiplier:
...
...
@@ -4225,6 +4316,13 @@ func (m *AccountMutation) AddField(name string, value ent.Value) error {
}
m.AddConcurrency(v)
return nil
case account.FieldLoadFactor:
v, ok := value.(int)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddLoadFactor(v)
return nil
case account.FieldPriority:
v, ok := value.(int)
if !ok {
...
...
@@ -4256,6 +4354,9 @@ func (m *AccountMutation) ClearedFields() []string {
if m.FieldCleared(account.FieldProxyID) {
fields = append(fields, account.FieldProxyID)
}
if m.FieldCleared(account.FieldLoadFactor) {
fields = append(fields, account.FieldLoadFactor)
}
if m.FieldCleared(account.FieldErrorMessage) {
fields = append(fields, account.FieldErrorMessage)
}
...
...
@@ -4312,6 +4413,9 @@ func (m *AccountMutation) ClearField(name string) error {
case account.FieldProxyID:
m.ClearProxyID()
return nil
case account.FieldLoadFactor:
m.ClearLoadFactor()
return nil
case account.FieldErrorMessage:
m.ClearErrorMessage()
return nil
...
...
@@ -4386,6 +4490,9 @@ func (m *AccountMutation) ResetField(name string) error {
case account.FieldConcurrency:
m.ResetConcurrency()
return nil
case account.FieldLoadFactor:
m.ResetLoadFactor()
return nil
case account.FieldPriority:
m.ResetPriority()
return nil
...
...
@@ -10191,7 +10298,7 @@ func (m *GroupMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *GroupMutation) Fields() []string {
fields := make([]string, 0, 3
0
)
fields := make([]string, 0, 3
1
)
if m.created_at != nil {
fields = append(fields, group.FieldCreatedAt)
}
...
...
backend/ent/runtime/runtime.go
View file @
63a8c769
...
...
@@ -212,29 +212,29 @@ func init() {
// account.DefaultConcurrency holds the default value on creation for the concurrency field.
account
.
DefaultConcurrency
=
accountDescConcurrency
.
Default
.
(
int
)
// accountDescPriority is the schema descriptor for priority field.
accountDescPriority
:=
accountFields
[
8
]
.
Descriptor
()
accountDescPriority
:=
accountFields
[
9
]
.
Descriptor
()
// account.DefaultPriority holds the default value on creation for the priority field.
account
.
DefaultPriority
=
accountDescPriority
.
Default
.
(
int
)
// accountDescRateMultiplier is the schema descriptor for rate_multiplier field.
accountDescRateMultiplier
:=
accountFields
[
9
]
.
Descriptor
()
accountDescRateMultiplier
:=
accountFields
[
10
]
.
Descriptor
()
// account.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
account
.
DefaultRateMultiplier
=
accountDescRateMultiplier
.
Default
.
(
float64
)
// accountDescStatus is the schema descriptor for status field.
accountDescStatus
:=
accountFields
[
1
0
]
.
Descriptor
()
accountDescStatus
:=
accountFields
[
1
1
]
.
Descriptor
()
// account.DefaultStatus holds the default value on creation for the status field.
account
.
DefaultStatus
=
accountDescStatus
.
Default
.
(
string
)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account
.
StatusValidator
=
accountDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// accountDescAutoPauseOnExpired is the schema descriptor for auto_pause_on_expired field.
accountDescAutoPauseOnExpired
:=
accountFields
[
1
4
]
.
Descriptor
()
accountDescAutoPauseOnExpired
:=
accountFields
[
1
5
]
.
Descriptor
()
// account.DefaultAutoPauseOnExpired holds the default value on creation for the auto_pause_on_expired field.
account
.
DefaultAutoPauseOnExpired
=
accountDescAutoPauseOnExpired
.
Default
.
(
bool
)
// accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable
:=
accountFields
[
1
5
]
.
Descriptor
()
accountDescSchedulable
:=
accountFields
[
1
6
]
.
Descriptor
()
// account.DefaultSchedulable holds the default value on creation for the schedulable field.
account
.
DefaultSchedulable
=
accountDescSchedulable
.
Default
.
(
bool
)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus
:=
accountFields
[
2
3
]
.
Descriptor
()
accountDescSessionWindowStatus
:=
accountFields
[
2
4
]
.
Descriptor
()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account
.
SessionWindowStatusValidator
=
accountDescSessionWindowStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
accountgroupFields
:=
schema
.
AccountGroup
{}
.
Fields
()
...
...
backend/ent/schema/account.go
View file @
63a8c769
...
...
@@ -97,6 +97,8 @@ func (Account) Fields() []ent.Field {
field
.
Int
(
"concurrency"
)
.
Default
(
3
),
field
.
Int
(
"load_factor"
)
.
Optional
()
.
Nillable
(),
// priority: 账户优先级,数值越小优先级越高
// 调度器会优先使用高优先级的账户
field
.
Int
(
"priority"
)
.
...
...
backend/go.sum
View file @
63a8c769
...
...
@@ -124,6 +124,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM=
github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
...
...
@@ -171,8 +173,6 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
...
...
@@ -182,7 +182,6 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
...
...
@@ -203,6 +202,8 @@ github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4=
github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
github.com/imroc/req/v3 v3.57.0 h1:LMTUjNRUybUkTPn8oJDq8Kg3JRBOBTcnDhKu7mzupKI=
github.com/imroc/req/v3 v3.57.0/go.mod h1:JL62ey1nvSLq81HORNcosvlf7SxZStONNqOprg0Pz00=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
...
...
@@ -285,6 +286,10 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkoukk/tiktoken-go v0.1.8 h1:85ENo+3FpWgAACBaEUVp+lctuTcYUO7BtmfhlN/QTRo=
github.com/pkoukk/tiktoken-go v0.1.8/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
github.com/pkoukk/tiktoken-go-loader v0.0.2 h1:LUKws63GV3pVHwH1srkBplBv+7URgmOmhSkRxsIvsK4=
github.com/pkoukk/tiktoken-go-loader v0.0.2/go.mod h1:4mIkYyZooFlnenDlormIo6cd5wrlUKNr97wp9nGgEKo=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
...
...
@@ -398,8 +403,6 @@ go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/Wgbsd
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
...
...
@@ -455,8 +458,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
...
...
backend/internal/handler/admin/account_handler.go
View file @
63a8c769
...
...
@@ -102,6 +102,7 @@ type CreateAccountRequest struct {
Concurrency
int
`json:"concurrency"`
Priority
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
LoadFactor
*
int
`json:"load_factor"`
GroupIDs
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
...
...
@@ -120,6 +121,7 @@ type UpdateAccountRequest struct {
Concurrency
*
int
`json:"concurrency"`
Priority
*
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
LoadFactor
*
int
`json:"load_factor"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
GroupIDs
*
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
...
...
@@ -135,6 +137,7 @@ type BulkUpdateAccountsRequest struct {
Concurrency
*
int
`json:"concurrency"`
Priority
*
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
LoadFactor
*
int
`json:"load_factor"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive error"`
Schedulable
*
bool
`json:"schedulable"`
GroupIDs
*
[]
int64
`json:"group_ids"`
...
...
@@ -506,6 +509,7 @@ func (h *AccountHandler) Create(c *gin.Context) {
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
RateMultiplier
:
req
.
RateMultiplier
,
LoadFactor
:
req
.
LoadFactor
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
AutoPauseOnExpired
:
req
.
AutoPauseOnExpired
,
...
...
@@ -575,6 +579,7 @@ func (h *AccountHandler) Update(c *gin.Context) {
Concurrency
:
req
.
Concurrency
,
// 指针类型,nil 表示未提供
Priority
:
req
.
Priority
,
// 指针类型,nil 表示未提供
RateMultiplier
:
req
.
RateMultiplier
,
LoadFactor
:
req
.
LoadFactor
,
Status
:
req
.
Status
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
...
...
@@ -1101,6 +1106,7 @@ func (h *AccountHandler) BulkUpdate(c *gin.Context) {
req
.
Concurrency
!=
nil
||
req
.
Priority
!=
nil
||
req
.
RateMultiplier
!=
nil
||
req
.
LoadFactor
!=
nil
||
req
.
Status
!=
""
||
req
.
Schedulable
!=
nil
||
req
.
GroupIDs
!=
nil
||
...
...
@@ -1119,6 +1125,7 @@ func (h *AccountHandler) BulkUpdate(c *gin.Context) {
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
RateMultiplier
:
req
.
RateMultiplier
,
LoadFactor
:
req
.
LoadFactor
,
Status
:
req
.
Status
,
Schedulable
:
req
.
Schedulable
,
GroupIDs
:
req
.
GroupIDs
,
...
...
backend/internal/handler/dto/mappers.go
View file @
63a8c769
...
...
@@ -183,6 +183,7 @@ func AccountFromServiceShallow(a *service.Account) *Account {
Extra
:
a
.
Extra
,
ProxyID
:
a
.
ProxyID
,
Concurrency
:
a
.
Concurrency
,
LoadFactor
:
a
.
LoadFactor
,
Priority
:
a
.
Priority
,
RateMultiplier
:
a
.
BillingRateMultiplier
(),
Status
:
a
.
Status
,
...
...
backend/internal/handler/dto/types.go
View file @
63a8c769
...
...
@@ -131,6 +131,7 @@ type Account struct {
Extra
map
[
string
]
any
`json:"extra"`
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
int
`json:"concurrency"`
LoadFactor
*
int
`json:"load_factor,omitempty"`
Priority
int
`json:"priority"`
RateMultiplier
float64
`json:"rate_multiplier"`
Status
string
`json:"status"`
...
...
backend/internal/repository/account_repo.go
View file @
63a8c769
...
...
@@ -84,6 +84,9 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
if
account
.
RateMultiplier
!=
nil
{
builder
.
SetRateMultiplier
(
*
account
.
RateMultiplier
)
}
if
account
.
LoadFactor
!=
nil
{
builder
.
SetLoadFactor
(
*
account
.
LoadFactor
)
}
if
account
.
ProxyID
!=
nil
{
builder
.
SetProxyID
(
*
account
.
ProxyID
)
...
...
@@ -318,6 +321,11 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
if
account
.
RateMultiplier
!=
nil
{
builder
.
SetRateMultiplier
(
*
account
.
RateMultiplier
)
}
if
account
.
LoadFactor
!=
nil
{
builder
.
SetLoadFactor
(
*
account
.
LoadFactor
)
}
else
{
builder
.
ClearLoadFactor
()
}
if
account
.
ProxyID
!=
nil
{
builder
.
SetProxyID
(
*
account
.
ProxyID
)
...
...
@@ -1223,6 +1231,15 @@ func (r *accountRepository) BulkUpdate(ctx context.Context, ids []int64, updates
args
=
append
(
args
,
*
updates
.
RateMultiplier
)
idx
++
}
if
updates
.
LoadFactor
!=
nil
{
if
*
updates
.
LoadFactor
<=
0
{
setClauses
=
append
(
setClauses
,
"load_factor = NULL"
)
}
else
{
setClauses
=
append
(
setClauses
,
"load_factor = $"
+
itoa
(
idx
))
args
=
append
(
args
,
*
updates
.
LoadFactor
)
idx
++
}
}
if
updates
.
Status
!=
nil
{
setClauses
=
append
(
setClauses
,
"status = $"
+
itoa
(
idx
))
args
=
append
(
args
,
*
updates
.
Status
)
...
...
@@ -1545,6 +1562,7 @@ func accountEntityToService(m *dbent.Account) *service.Account {
Concurrency
:
m
.
Concurrency
,
Priority
:
m
.
Priority
,
RateMultiplier
:
&
rateMultiplier
,
LoadFactor
:
m
.
LoadFactor
,
Status
:
m
.
Status
,
ErrorMessage
:
derefString
(
m
.
ErrorMessage
),
LastUsedAt
:
m
.
LastUsedAt
,
...
...
backend/internal/service/account.go
View file @
63a8c769
...
...
@@ -28,6 +28,7 @@ type Account struct {
// RateMultiplier 账号计费倍率(>=0,允许 0 表示该账号计费为 0)。
// 使用指针用于兼容旧版本调度缓存(Redis)中缺字段的情况:nil 表示按 1.0 处理。
RateMultiplier
*
float64
LoadFactor
*
int
// 调度负载因子;nil 表示使用 Concurrency
Status
string
ErrorMessage
string
LastUsedAt
*
time
.
Time
...
...
@@ -88,6 +89,19 @@ func (a *Account) BillingRateMultiplier() float64 {
return
*
a
.
RateMultiplier
}
func
(
a
*
Account
)
EffectiveLoadFactor
()
int
{
if
a
==
nil
{
return
1
}
if
a
.
LoadFactor
!=
nil
&&
*
a
.
LoadFactor
>
0
{
return
*
a
.
LoadFactor
}
if
a
.
Concurrency
>
0
{
return
a
.
Concurrency
}
return
1
}
func
(
a
*
Account
)
IsSchedulable
()
bool
{
if
!
a
.
IsActive
()
||
!
a
.
Schedulable
{
return
false
...
...
backend/internal/service/account_load_factor_test.go
0 → 100644
View file @
63a8c769
//go:build unit
package
service
import
(
"testing"
"github.com/stretchr/testify/require"
)
func
intPtrHelper
(
v
int
)
*
int
{
return
&
v
}
func
TestEffectiveLoadFactor_NilAccount
(
t
*
testing
.
T
)
{
var
a
*
Account
require
.
Equal
(
t
,
1
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_NilLoadFactor_PositiveConcurrency
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
5
}
require
.
Equal
(
t
,
5
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_NilLoadFactor_ZeroConcurrency
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
0
}
require
.
Equal
(
t
,
1
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_PositiveLoadFactor
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
5
,
LoadFactor
:
intPtrHelper
(
20
)}
require
.
Equal
(
t
,
20
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_ZeroLoadFactor_FallbackToConcurrency
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
5
,
LoadFactor
:
intPtrHelper
(
0
)}
require
.
Equal
(
t
,
5
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_NegativeLoadFactor_FallbackToConcurrency
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
3
,
LoadFactor
:
intPtrHelper
(
-
1
)}
require
.
Equal
(
t
,
3
,
a
.
EffectiveLoadFactor
())
}
func
TestEffectiveLoadFactor_ZeroLoadFactor_ZeroConcurrency
(
t
*
testing
.
T
)
{
a
:=
&
Account
{
Concurrency
:
0
,
LoadFactor
:
intPtrHelper
(
0
)}
require
.
Equal
(
t
,
1
,
a
.
EffectiveLoadFactor
())
}
backend/internal/service/account_service.go
View file @
63a8c769
...
...
@@ -82,6 +82,7 @@ type AccountBulkUpdate struct {
Concurrency
*
int
Priority
*
int
RateMultiplier
*
float64
LoadFactor
*
int
Status
*
string
Schedulable
*
bool
Credentials
map
[
string
]
any
...
...
backend/internal/service/admin_service.go
View file @
63a8c769
...
...
@@ -196,6 +196,7 @@ type CreateAccountInput struct {
Concurrency
int
Priority
int
RateMultiplier
*
float64
// 账号计费倍率(>=0,允许 0)
LoadFactor
*
int
GroupIDs
[]
int64
ExpiresAt
*
int64
AutoPauseOnExpired
*
bool
...
...
@@ -216,6 +217,7 @@ type UpdateAccountInput struct {
Concurrency
*
int
// 使用指针区分"未提供"和"设置为0"
Priority
*
int
// 使用指针区分"未提供"和"设置为0"
RateMultiplier
*
float64
// 账号计费倍率(>=0,允许 0)
LoadFactor
*
int
Status
string
GroupIDs
*
[]
int64
ExpiresAt
*
int64
...
...
@@ -231,6 +233,7 @@ type BulkUpdateAccountsInput struct {
Concurrency
*
int
Priority
*
int
RateMultiplier
*
float64
// 账号计费倍率(>=0,允许 0)
LoadFactor
*
int
Status
string
Schedulable
*
bool
GroupIDs
*
[]
int64
...
...
@@ -1414,6 +1417,12 @@ func (s *adminServiceImpl) CreateAccount(ctx context.Context, input *CreateAccou
}
account
.
RateMultiplier
=
input
.
RateMultiplier
}
if
input
.
LoadFactor
!=
nil
&&
*
input
.
LoadFactor
>
0
{
if
*
input
.
LoadFactor
>
10000
{
return
nil
,
errors
.
New
(
"load_factor must be <= 10000"
)
}
account
.
LoadFactor
=
input
.
LoadFactor
}
if
err
:=
s
.
accountRepo
.
Create
(
ctx
,
account
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -1488,6 +1497,15 @@ func (s *adminServiceImpl) UpdateAccount(ctx context.Context, id int64, input *U
}
account
.
RateMultiplier
=
input
.
RateMultiplier
}
if
input
.
LoadFactor
!=
nil
{
if
*
input
.
LoadFactor
<=
0
{
account
.
LoadFactor
=
nil
// 0 或负数表示清除
}
else
if
*
input
.
LoadFactor
>
10000
{
return
nil
,
errors
.
New
(
"load_factor must be <= 10000"
)
}
else
{
account
.
LoadFactor
=
input
.
LoadFactor
}
}
if
input
.
Status
!=
""
{
account
.
Status
=
input
.
Status
}
...
...
@@ -1621,6 +1639,15 @@ func (s *adminServiceImpl) BulkUpdateAccounts(ctx context.Context, input *BulkUp
if
input
.
RateMultiplier
!=
nil
{
repoUpdates
.
RateMultiplier
=
input
.
RateMultiplier
}
if
input
.
LoadFactor
!=
nil
{
if
*
input
.
LoadFactor
<=
0
{
repoUpdates
.
LoadFactor
=
nil
// 0 或负数表示清除
}
else
if
*
input
.
LoadFactor
>
10000
{
return
nil
,
errors
.
New
(
"load_factor must be <= 10000"
)
}
else
{
repoUpdates
.
LoadFactor
=
input
.
LoadFactor
}
}
if
input
.
Status
!=
""
{
repoUpdates
.
Status
=
&
input
.
Status
}
...
...
backend/internal/service/gateway_service.go
View file @
63a8c769
...
...
@@ -1316,7 +1316,7 @@ func (s *GatewayService) SelectAccountWithLoadAwareness(ctx context.Context, gro
for
_
,
acc
:=
range
routingCandidates
{
routingLoads
=
append
(
routingLoads
,
AccountWithConcurrency
{
ID
:
acc
.
ID
,
MaxConcurrency
:
acc
.
Concurrency
,
MaxConcurrency
:
acc
.
EffectiveLoadFactor
()
,
})
}
routingLoadMap
,
_
:=
s
.
concurrencyService
.
GetAccountsLoadBatch
(
ctx
,
routingLoads
)
...
...
@@ -1509,7 +1509,7 @@ func (s *GatewayService) SelectAccountWithLoadAwareness(ctx context.Context, gro
for
_
,
acc
:=
range
candidates
{
accountLoads
=
append
(
accountLoads
,
AccountWithConcurrency
{
ID
:
acc
.
ID
,
MaxConcurrency
:
acc
.
Concurrency
,
MaxConcurrency
:
acc
.
EffectiveLoadFactor
()
,
})
}
...
...
backend/internal/service/openai_account_scheduler.go
View file @
63a8c769
...
...
@@ -342,6 +342,7 @@ func (s *defaultOpenAIAccountScheduler) selectBySessionHash(
}
cfg
:=
s
.
service
.
schedulingConfig
()
// WaitPlan.MaxConcurrency 使用 Concurrency(非 EffectiveLoadFactor),因为 WaitPlan 控制的是 Redis 实际并发槽位等待。
if
s
.
service
.
concurrencyService
!=
nil
{
return
&
AccountSelectionResult
{
Account
:
account
,
...
...
@@ -590,7 +591,7 @@ func (s *defaultOpenAIAccountScheduler) selectByLoadBalance(
filtered
=
append
(
filtered
,
account
)
loadReq
=
append
(
loadReq
,
AccountWithConcurrency
{
ID
:
account
.
ID
,
MaxConcurrency
:
account
.
Concurrency
,
MaxConcurrency
:
account
.
EffectiveLoadFactor
()
,
})
}
if
len
(
filtered
)
==
0
{
...
...
@@ -703,6 +704,7 @@ func (s *defaultOpenAIAccountScheduler) selectByLoadBalance(
}
cfg
:=
s
.
service
.
schedulingConfig
()
// WaitPlan.MaxConcurrency 使用 Concurrency(非 EffectiveLoadFactor),因为 WaitPlan 控制的是 Redis 实际并发槽位等待。
candidate
:=
selectionOrder
[
0
]
return
&
AccountSelectionResult
{
Account
:
candidate
.
account
,
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment