feat: GetTrends 趋势查询并行化 (errgroup)

- 使用 golang.org/x/sync/errgroup 将 4 个独立 DB 查询并行执行
- Energy/Comments/Likes/Favorites 趋势查询不再串行阻塞
- golang.org/x/sync 由 indirect 改为 direct 依赖
This commit is contained in:
2026-06-02 19:37:43 +08:00
parent ab26704049
commit 95e1728c6e
2 changed files with 53 additions and 31 deletions

2
go.mod
View File

@ -9,6 +9,7 @@ require (
github.com/spf13/viper v1.21.0 github.com/spf13/viper v1.21.0
golang.org/x/crypto v0.52.0 golang.org/x/crypto v0.52.0
golang.org/x/image v0.41.0 golang.org/x/image v0.41.0
golang.org/x/sync v0.20.0
gorm.io/driver/postgres v1.6.0 gorm.io/driver/postgres v1.6.0
gorm.io/gorm v1.31.1 gorm.io/gorm v1.31.1
) )
@ -56,7 +57,6 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.22.0 // indirect golang.org/x/arch v0.22.0 // indirect
golang.org/x/net v0.54.0 // indirect golang.org/x/net v0.54.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.45.0 // indirect golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect golang.org/x/text v0.37.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect google.golang.org/protobuf v1.36.10 // indirect

View File

@ -1,6 +1,10 @@
package service package service
import "fmt" import (
"fmt"
"golang.org/x/sync/errgroup"
)
// TrendResult 趋势返回结构 // TrendResult 趋势返回结构
type TrendResult struct { type TrendResult struct {
@ -28,32 +32,50 @@ func NewTrendsService(energyRepo EnergyTrendStore, commentRepo CommentTrendStore
} }
} }
// GetTrends 获取指定时间范围的趋势数据 // GetTrends 获取指定时间范围的趋势数据(并行查询四项趋势)
func (s *TrendsService) GetTrends(userID uint, since string) (*TrendResult, error) { func (s *TrendsService) GetTrends(userID uint, since string) (*TrendResult, error) {
energy, err := s.energyRepo.AggregateEnergyByAuthor(userID, since) result := &TrendResult{}
g := new(errgroup.Group)
g.Go(func() error {
var err error
result.Energy, err = s.energyRepo.AggregateEnergyByAuthor(userID, since)
if err != nil { if err != nil {
return nil, fmt.Errorf("查询赋能趋势: %w", err) return fmt.Errorf("查询赋能趋势: %w", err)
}
return nil
})
g.Go(func() error {
var err error
result.Comments, err = s.commentRepo.AggregateCommentsByAuthor(userID, since)
if err != nil {
return fmt.Errorf("查询评论趋势: %w", err)
}
return nil
})
g.Go(func() error {
var err error
result.Likes, err = s.likeRepo.AggregateLikesByAuthor(userID, since)
if err != nil {
return fmt.Errorf("查询点赞趋势: %w", err)
}
return nil
})
g.Go(func() error {
var err error
result.Favorites, err = s.favoriteRepo.AggregateFavoritesByAuthor(userID, since)
if err != nil {
return fmt.Errorf("查询收藏趋势: %w", err)
}
return nil
})
if err := g.Wait(); err != nil {
return nil, err
} }
comments, err := s.commentRepo.AggregateCommentsByAuthor(userID, since) return result, nil
if err != nil {
return nil, fmt.Errorf("查询评论趋势: %w", err)
}
likes, err := s.likeRepo.AggregateLikesByAuthor(userID, since)
if err != nil {
return nil, fmt.Errorf("查询点赞趋势: %w", err)
}
favorites, err := s.favoriteRepo.AggregateFavoritesByAuthor(userID, since)
if err != nil {
return nil, fmt.Errorf("查询收藏趋势: %w", err)
}
return &TrendResult{
Energy: energy,
Comments: comments,
Likes: likes,
Favorites: favorites,
}, nil
} }