package sniper import ( "sort" "time" ) // emitSummary 在任务结束时回调一次汇总;OnSummary 为 nil 时不做任何事。 func (r *Runner) emitSummary(state *runState, accounts, targets, attempts int, cost time.Duration) { if r.OnSummary == nil { return } stats := state.snapshotStats() summary := RunSummary{ Attempts: attempts, Accounts: accounts, Targets: targets, Duration: cost, ListReqs: stats.listReqs, ExchangeReqs: stats.exchangeReqs, ScoreReqs: stats.scoreReqs, RecordReqs: stats.recordReqs, SuccessUIDs: len(stats.successUIDs), Outcomes: stats.outcomes, } if state.windowed() { summary.OpenAt = state.openAt summary.WindowSeconds = int(state.windowLen / time.Second) } for _, kind := range []requestKind{reqList, reqExchange, reqScore, reqRecord} { stat := stats.requests[kind] if stat == nil || stat.count == 0 { continue } summary.RequestStats = append(summary.RequestStats, RequestStat{ Kind: kind.String(), Count: stat.count, Failed: stat.failed, Total: stat.total, Slowest: stat.slowest, LastErr: stat.lastErr, }) } uids := make([]int64, 0, len(stats.accounts)) for uid := range stats.accounts { uids = append(uids, uid) } sort.Slice(uids, func(i, j int) bool { return uids[i] < uids[j] }) for _, uid := range uids { summary.AccountOutcomes = append(summary.AccountOutcomes, *stats.accounts[uid]) } r.OnSummary(summary) }