github.com/wfusion/gofusion@v1.1.14/redis/construct.go (about)

     1  package redis
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  	"reflect"
     7  	"syscall"
     8  
     9  	rdsDrv "github.com/redis/go-redis/v9"
    10  	"github.com/wfusion/gofusion/common/di"
    11  	"github.com/wfusion/gofusion/common/infra/drivers/redis"
    12  	"github.com/wfusion/gofusion/common/utils"
    13  	"github.com/wfusion/gofusion/common/utils/inspect"
    14  	"github.com/wfusion/gofusion/config"
    15  
    16  	fusLog "github.com/wfusion/gofusion/log"
    17  
    18  	_ "github.com/wfusion/gofusion/log/customlogger"
    19  )
    20  
    21  func Construct(ctx context.Context, confs map[string]*Conf, opts ...utils.OptionExtender) func() {
    22  	opt := utils.ApplyOptions[config.InitOption](opts...)
    23  	optU := utils.ApplyOptions[useOption](opts...)
    24  	if opt.AppName == "" {
    25  		opt.AppName = optU.appName
    26  	}
    27  
    28  	for name, conf := range confs {
    29  		addInstance(ctx, name, conf, opt)
    30  	}
    31  	return func() {
    32  		rwlock.Lock()
    33  		defer rwlock.Unlock()
    34  
    35  		pid := syscall.Getpid()
    36  		app := config.Use(opt.AppName).AppName()
    37  		if appInstances != nil {
    38  			for name, instance := range appInstances[opt.AppName] {
    39  				if err := instance.GetProxy().Close(); err != nil {
    40  					log.Printf("%v [Gofusion] %s %s %s close error: %s",
    41  						pid, app, config.ComponentRedis, name, err)
    42  				}
    43  			}
    44  			delete(appInstances, opt.AppName)
    45  		}
    46  	}
    47  }
    48  
    49  func addInstance(ctx context.Context, name string, conf *Conf, opt *config.InitOption) {
    50  	var hooks []rdsDrv.Hook
    51  	for _, hookLoc := range conf.Hooks {
    52  		if hookType := inspect.TypeOf(hookLoc); hookType != nil {
    53  			hookValue := reflect.New(hookType)
    54  			if hookValue.Type().Implements(customLoggerType) {
    55  				logger := fusLog.Use(conf.LogInstance, fusLog.AppName(opt.AppName))
    56  				hookValue.Interface().(customLogger).Init(logger, opt.AppName, name)
    57  			}
    58  
    59  			hooks = append(hooks, hookValue.Interface().(rdsDrv.Hook))
    60  		}
    61  	}
    62  
    63  	// conf.Option.Password = config.CryptoDecryptFunc()(conf.Option.Password)
    64  	rdsCli, err := redis.Default.New(ctx, conf.Option, redis.WithHook(hooks))
    65  	if err != nil {
    66  		panic(err)
    67  	}
    68  
    69  	rwlock.Lock()
    70  	defer rwlock.Unlock()
    71  	if appInstances == nil {
    72  		appInstances = make(map[string]map[string]*instance)
    73  	}
    74  	if appInstances[opt.AppName] == nil {
    75  		appInstances[opt.AppName] = make(map[string]*instance)
    76  	}
    77  	if _, ok := appInstances[opt.AppName][name]; ok {
    78  		panic(ErrDuplicatedName)
    79  	}
    80  	appInstances[opt.AppName][name] = &instance{name: name, redis: rdsCli}
    81  
    82  	if opt.DI != nil {
    83  		opt.DI.MustProvide(func() rdsDrv.UniversalClient { return Use(ctx, name, AppName(opt.AppName)) }, di.Name(name))
    84  	}
    85  
    86  	go startDaemonRoutines(ctx, opt.AppName, name, conf)
    87  }
    88  
    89  func init() {
    90  	config.AddComponent(config.ComponentRedis, Construct, config.WithFlag(&flagString))
    91  }