90 lines
2.3 KiB
Go
90 lines
2.3 KiB
Go
package scenarios
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"net/http"
|
||
"sync/atomic"
|
||
"time"
|
||
|
||
"github.com/topfans/backend/scripts/loadgen/loadgen/lib"
|
||
)
|
||
|
||
var (
|
||
s6Dimensions = []string{"displaying", "month", "total"}
|
||
s6StarIDs = []int64{87, 88, 93, 999900}
|
||
s6Endpoints = []string{"/api/v1/rankings/hot", "/api/v1/rankings/original"}
|
||
)
|
||
|
||
type s6Ranking struct {
|
||
client *http.Client
|
||
users []lib.TestUser
|
||
errCount *atomic.Int64
|
||
totalCount *atomic.Int64
|
||
fiveXXCount *atomic.Int64
|
||
rec *lib.LatencyRecorder
|
||
breaker *lib.CircuitBreaker
|
||
baseURL string
|
||
}
|
||
|
||
func init() { register("S6", newS6) }
|
||
|
||
func newS6(c *http.Client, u []lib.TestUser, e, t, f *atomic.Int64, r *lib.LatencyRecorder, b *lib.CircuitBreaker, ssh string) Scenario {
|
||
return &s6Ranking{client: c, users: u, errCount: e, totalCount: t, fiveXXCount: f, rec: r, breaker: b, baseURL: DefaultBaseURL}
|
||
}
|
||
|
||
func (s *s6Ranking) Run(ctx context.Context, rpsOverride int, durationOverride time.Duration, dash *lib.Dashboard, breaker *lib.CircuitBreaker, stages []int) error {
|
||
schedule := stages
|
||
if len(schedule) == 0 {
|
||
rps := rpsOverride
|
||
if rps == 0 {
|
||
rps = 300
|
||
}
|
||
schedule = []int{rps}
|
||
}
|
||
stageDuration := durationOverride
|
||
if stageDuration == 0 {
|
||
stageDuration = 2 * time.Minute
|
||
}
|
||
|
||
for stageIdx, stageRPS := range schedule {
|
||
logf("S6 stage %d/%d: %d RPS × %v", stageIdx+1, len(schedule), stageRPS, stageDuration)
|
||
s.rec.BeginStage(stageIdx+1, stageRPS)
|
||
if err := s.runStage(ctx, stageRPS, stageDuration); err != nil {
|
||
s.rec.EndStage()
|
||
return err
|
||
}
|
||
s.rec.EndStage()
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (s *s6Ranking) runStage(ctx context.Context, rps int, duration time.Duration) error {
|
||
ticker := time.NewTicker(time.Second / time.Duration(rps))
|
||
defer ticker.Stop()
|
||
timeout := time.NewTimer(duration)
|
||
defer timeout.Stop()
|
||
for {
|
||
select {
|
||
case <-ctx.Done():
|
||
return nil
|
||
case <-timeout.C:
|
||
return nil
|
||
case <-ticker.C:
|
||
s.doOne()
|
||
}
|
||
}
|
||
}
|
||
|
||
func (s *s6Ranking) doOne() {
|
||
for _, ep := range s6Endpoints {
|
||
for _, dim := range s6Dimensions {
|
||
for _, sid := range s6StarIDs {
|
||
url := fmt.Sprintf("%s%s?dimension=%s&star_id=%d&page=1&page_size=10", s.baseURL, ep, dim, sid)
|
||
req, _ := http.NewRequest("GET", url, nil)
|
||
doRequest(s.client, req, s.rec, s.errCount, s.totalCount, s.fiveXXCount, s.breaker)
|
||
}
|
||
}
|
||
}
|
||
}
|