123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package service
- import (
- "fmt"
- "sync"
- "time"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/context"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/log"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/module"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/recconf"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/service/feature"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/utils"
- )
- var featureService *FeatureService
- type FeatureFunc func(user *module.User, items []*module.Item, context *context.RecommendContext) []*module.Item
- type LoadFeatureFunc func(user *module.User, items []*module.Item, context *context.RecommendContext)
- func init() {
- featureService = &FeatureService{
- featureSceneMap: make(map[string][]*feature.Feature),
- featureSceneAsyncMap: make(map[string]bool),
- featureFuncMap: make(map[string]FeatureFunc),
- loadFeatureFuncMap: make(map[string]LoadFeatureFunc),
- }
- }
- func DefaultFeatureService() *FeatureService {
- return featureService
- }
- func RegisterFeatureFunc(sceneName string, f FeatureFunc) {
- DefaultFeatureService().AddFeatureFunc(sceneName, f)
- }
- func RegisterLoadFeatureFunc(sceneName string, f LoadFeatureFunc) {
- DefaultFeatureService().AddLoadFeatureFunc(sceneName, f)
- }
- type FeatureService struct {
- featureSceneMap map[string][]*feature.Feature
- featureSceneAsyncMap map[string]bool
- featureFuncMap map[string]FeatureFunc
- loadFeatureFuncMap map[string]LoadFeatureFunc
- }
- func (s *FeatureService) AddFeatureFunc(sceneName string, f FeatureFunc) {
- s.featureFuncMap[sceneName] = f
- }
- func (s *FeatureService) AddLoadFeatureFunc(sceneName string, f LoadFeatureFunc) {
- s.loadFeatureFuncMap[sceneName] = f
- }
- // LoadFeatures load user or item feature use feature.Feature
- func (s *FeatureService) LoadFeatures(user *module.User, items []*module.Item, context *context.RecommendContext) []*module.Item {
- start := time.Now()
- var sceneName string
- if context.ExperimentResult != nil {
- sceneName = context.ExperimentResult.GetExperimentParams().GetString("features.scene.name", "")
- }
- if sceneName == "" {
- sceneName = context.GetParameter("scene").(string)
- }
- if features, ok := s.featureSceneMap[sceneName]; ok {
- async := s.featureSceneAsyncMap[sceneName]
- if async {
- var wg sync.WaitGroup
- for _, fea := range features {
- wg.Add(1)
- go func(fea *feature.Feature) {
- defer wg.Done()
- fea.LoadFeatures(user, items, context)
- }(fea)
- }
- if loadFeatureFunc, exist := s.loadFeatureFuncMap[sceneName]; exist {
- wg.Add(1)
- go func() {
- defer wg.Done()
- loadFeatureFunc(user, items, context)
- }()
- }
- wg.Wait()
- } else {
- for _, feature := range features {
- feature.LoadFeatures(user, items, context)
- }
- if loadFeatureFunc, exist := s.loadFeatureFuncMap[sceneName]; exist {
- loadFeatureFunc(user, items, context)
- }
- }
- featureFunc, ok := s.featureFuncMap[sceneName]
- if ok {
- items = featureFunc(user, items, context)
- }
- }
- log.Info(fmt.Sprintf("requestId=%s\tmodule=LoadFeatures\tcost=%d", context.RecommendId, utils.CostTime(start)))
- return items
- }
- func (s *FeatureService) LoadFeaturesForGeneralRank(user *module.User, items []*module.Item, context *context.RecommendContext) {
- start := time.Now()
- sceneName := context.GetParameter("scene").(string)
- if features, ok := s.featureSceneMap[sceneName]; ok {
- async := s.featureSceneAsyncMap[sceneName]
- if async {
- var wg sync.WaitGroup
- for _, fea := range features {
- wg.Add(1)
- go func(fea *feature.Feature) {
- defer wg.Done()
- fea.LoadFeatures(user, items, context)
- }(fea)
- }
- wg.Wait()
- } else {
- for _, feature := range features {
- feature.LoadFeatures(user, items, context)
- }
- }
- // featureFunc, ok := s.featureFuncMap[sceneName]
- // if ok {
- // featureFunc(user, items, context)
- // }
- }
- log.Info(fmt.Sprintf("requestId=%s\tmodule=LoadFeaturesForGeneralRank\tcost=%d", context.RecommendId, utils.CostTime(start)))
- }
- func LoadFeatureConfig(config *recconf.RecommendConfig) {
- for name, sceneConf := range config.FeatureConfs {
- var features []*feature.Feature
- for _, conf := range sceneConf.FeatureLoadConfs {
- f := feature.LoadWithConfig(conf)
- features = append(features, f)
- }
- featureService.featureSceneAsyncMap[name] = false
- if sceneConf.AsynLoadFeature {
- featureService.featureSceneAsyncMap[name] = true
- }
- featureService.featureSceneMap[name] = features
- }
- }
|