topfans/backend/scripts/loadgen/loadgen/scenarios/s6_ranking.go
2026-06-15 21:12:59 +08:00

90 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}
}
}