Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
433f7aff
authored
Dec 27, 2023
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 加入渠道加权随机功能
parent
18a9c2b5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
86 additions
and
8 deletions
+86
-8
common/utils.go
+5
-0
model/ability.go
+30
-5
model/cache.go
+24
-2
model/channel.go
+7
-0
web/src/components/ChannelsTable.js
+20
-1
No files found.
common/utils.go
View file @
433f7aff
...
@@ -168,6 +168,11 @@ func GetRandomString(length int) string {
...
@@ -168,6 +168,11 @@ func GetRandomString(length int) string {
return
string
(
key
)
return
string
(
key
)
}
}
func
GetRandomInt
(
max
int
)
int
{
//rand.Seed(time.Now().UnixNano())
return
rand
.
Intn
(
max
)
}
func
GetTimestamp
()
int64
{
func
GetTimestamp
()
int64
{
return
time
.
Now
()
.
Unix
()
return
time
.
Now
()
.
Unix
()
}
}
...
...
model/ability.go
View file @
433f7aff
...
@@ -11,6 +11,7 @@ type Ability struct {
...
@@ -11,6 +11,7 @@ type Ability struct {
ChannelId
int
`json:"channel_id" gorm:"primaryKey;autoIncrement:false;index"`
ChannelId
int
`json:"channel_id" gorm:"primaryKey;autoIncrement:false;index"`
Enabled
bool
`json:"enabled"`
Enabled
bool
`json:"enabled"`
Priority
*
int64
`json:"priority" gorm:"bigint;default:0;index"`
Priority
*
int64
`json:"priority" gorm:"bigint;default:0;index"`
Weight
uint
`json:"weight" gorm:"default:0;index"`
}
}
func
GetGroupModels
(
group
string
)
[]
string
{
func
GetGroupModels
(
group
string
)
[]
string
{
...
@@ -25,7 +26,7 @@ func GetGroupModels(group string) []string {
...
@@ -25,7 +26,7 @@ func GetGroupModels(group string) []string {
}
}
func
GetRandomSatisfiedChannel
(
group
string
,
model
string
)
(
*
Channel
,
error
)
{
func
GetRandomSatisfiedChannel
(
group
string
,
model
string
)
(
*
Channel
,
error
)
{
ability
:=
Ability
{}
var
abilities
[]
Ability
groupCol
:=
"`group`"
groupCol
:=
"`group`"
trueVal
:=
"1"
trueVal
:=
"1"
if
common
.
UsingPostgreSQL
{
if
common
.
UsingPostgreSQL
{
...
@@ -37,16 +38,39 @@ func GetRandomSatisfiedChannel(group string, model string) (*Channel, error) {
...
@@ -37,16 +38,39 @@ func GetRandomSatisfiedChannel(group string, model string) (*Channel, error) {
maxPrioritySubQuery
:=
DB
.
Model
(
&
Ability
{})
.
Select
(
"MAX(priority)"
)
.
Where
(
groupCol
+
" = ? and model = ? and enabled = "
+
trueVal
,
group
,
model
)
maxPrioritySubQuery
:=
DB
.
Model
(
&
Ability
{})
.
Select
(
"MAX(priority)"
)
.
Where
(
groupCol
+
" = ? and model = ? and enabled = "
+
trueVal
,
group
,
model
)
channelQuery
:=
DB
.
Where
(
groupCol
+
" = ? and model = ? and enabled = "
+
trueVal
+
" and priority = (?)"
,
group
,
model
,
maxPrioritySubQuery
)
channelQuery
:=
DB
.
Where
(
groupCol
+
" = ? and model = ? and enabled = "
+
trueVal
+
" and priority = (?)"
,
group
,
model
,
maxPrioritySubQuery
)
if
common
.
UsingSQLite
||
common
.
UsingPostgreSQL
{
if
common
.
UsingSQLite
||
common
.
UsingPostgreSQL
{
err
=
channelQuery
.
Order
(
"
RANDOM()"
)
.
First
(
&
ability
)
.
Error
err
=
channelQuery
.
Order
(
"
weight DESC"
)
.
Find
(
&
abilities
)
.
Error
}
else
{
}
else
{
err
=
channelQuery
.
Order
(
"
RAND()"
)
.
First
(
&
ability
)
.
Error
err
=
channelQuery
.
Order
(
"
weight DESC"
)
.
Find
(
&
abilities
)
.
Error
}
}
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
channel
:=
Channel
{}
channel
:=
Channel
{}
channel
.
Id
=
ability
.
ChannelId
if
len
(
abilities
)
>
0
{
err
=
DB
.
First
(
&
channel
,
"id = ?"
,
ability
.
ChannelId
)
.
Error
// Randomly choose one
weightSum
:=
uint
(
0
)
for
_
,
ability_
:=
range
abilities
{
weightSum
+=
ability_
.
Weight
}
if
weightSum
==
0
{
// All weight is 0, randomly choose one
channel
.
Id
=
abilities
[
common
.
GetRandomInt
(
len
(
abilities
))]
.
ChannelId
}
else
{
// Randomly choose one
weight
:=
common
.
GetRandomInt
(
int
(
weightSum
))
for
_
,
ability_
:=
range
abilities
{
weight
-=
int
(
ability_
.
Weight
)
//log.Printf("weight: %d, ability weight: %d", weight, *ability_.Weight)
if
weight
<=
0
{
channel
.
Id
=
ability_
.
ChannelId
break
}
}
}
}
else
{
return
nil
,
nil
}
err
=
DB
.
First
(
&
channel
,
"id = ?"
,
channel
.
Id
)
.
Error
return
&
channel
,
err
return
&
channel
,
err
}
}
...
@@ -62,6 +86,7 @@ func (channel *Channel) AddAbilities() error {
...
@@ -62,6 +86,7 @@ func (channel *Channel) AddAbilities() error {
ChannelId
:
channel
.
Id
,
ChannelId
:
channel
.
Id
,
Enabled
:
channel
.
Status
==
common
.
ChannelStatusEnabled
,
Enabled
:
channel
.
Status
==
common
.
ChannelStatusEnabled
,
Priority
:
channel
.
Priority
,
Priority
:
channel
.
Priority
,
Weight
:
uint
(
channel
.
GetWeight
()),
}
}
abilities
=
append
(
abilities
,
ability
)
abilities
=
append
(
abilities
,
ability
)
}
}
...
...
model/cache.go
View file @
433f7aff
...
@@ -198,6 +198,7 @@ func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error
...
@@ -198,6 +198,7 @@ func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error
model
=
"gpt-4-gizmo-*"
model
=
"gpt-4-gizmo-*"
}
}
// if memory cache is disabled, get channel directly from database
if
!
common
.
MemoryCacheEnabled
{
if
!
common
.
MemoryCacheEnabled
{
return
GetRandomSatisfiedChannel
(
group
,
model
)
return
GetRandomSatisfiedChannel
(
group
,
model
)
}
}
...
@@ -218,8 +219,29 @@ func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error
...
@@ -218,8 +219,29 @@ func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error
}
}
}
}
}
}
idx
:=
rand
.
Intn
(
endIdx
)
// Calculate the total weight of all channels up to endIdx
return
channels
[
idx
],
nil
totalWeight
:=
0
for
_
,
channel
:=
range
channels
[
:
endIdx
]
{
totalWeight
+=
channel
.
GetWeight
()
}
if
totalWeight
==
0
{
// If all weights are 0, select a channel randomly
return
channels
[
rand
.
Intn
(
endIdx
)],
nil
}
// Generate a random value in the range [0, totalWeight)
randomWeight
:=
rand
.
Intn
(
totalWeight
)
// Find a channel based on its weight
for
_
,
channel
:=
range
channels
[
:
endIdx
]
{
randomWeight
-=
channel
.
GetWeight
()
if
randomWeight
<=
0
{
return
channel
,
nil
}
}
// return the last channel if no channel is found
return
channels
[
endIdx
-
1
],
nil
}
}
func
CacheGetChannel
(
id
int
)
(
*
Channel
,
error
)
{
func
CacheGetChannel
(
id
int
)
(
*
Channel
,
error
)
{
...
...
model/channel.go
View file @
433f7aff
...
@@ -113,6 +113,13 @@ func (channel *Channel) GetPriority() int64 {
...
@@ -113,6 +113,13 @@ func (channel *Channel) GetPriority() int64 {
return
*
channel
.
Priority
return
*
channel
.
Priority
}
}
func
(
channel
*
Channel
)
GetWeight
()
int
{
if
channel
.
Weight
==
nil
{
return
0
}
return
int
(
*
channel
.
Weight
)
}
func
(
channel
*
Channel
)
GetBaseURL
()
string
{
func
(
channel
*
Channel
)
GetBaseURL
()
string
{
if
channel
.
BaseURL
==
nil
{
if
channel
.
BaseURL
==
nil
{
return
""
return
""
...
...
web/src/components/ChannelsTable.js
View file @
433f7aff
...
@@ -163,7 +163,7 @@ const ChannelsTable = () => {
...
@@ -163,7 +163,7 @@ const ChannelsTable = () => {
<
div
>
<
div
>
<
InputNumber
<
InputNumber
style
=
{{
width
:
70
}}
style
=
{{
width
:
70
}}
name
=
'
name
'
name
=
'
priority
'
onChange
=
{
value
=>
{
onChange
=
{
value
=>
{
manageChannel
(
record
.
id
,
'priority'
,
record
,
value
);
manageChannel
(
record
.
id
,
'priority'
,
record
,
value
);
}}
}}
...
@@ -175,6 +175,25 @@ const ChannelsTable = () => {
...
@@ -175,6 +175,25 @@ const ChannelsTable = () => {
},
},
},
},
{
{
title
:
'权重'
,
dataIndex
:
'weight'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
<
div
>
<
InputNumber
style
=
{{
width
:
70
}}
name
=
'weight'
onChange
=
{
value
=>
{
manageChannel
(
record
.
id
,
'weight'
,
record
,
value
);
}}
defaultValue
=
{
record
.
weight
}
min
=
{
0
}
/
>
<
/div
>
);
},
},
{
title
:
''
,
title
:
''
,
dataIndex
:
'operate'
,
dataIndex
:
'operate'
,
render
:
(
text
,
record
,
index
)
=>
(
render
:
(
text
,
record
,
index
)
=>
(
...
...
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