open-im-server/pkg/common/config/load_config.go
chao 10a577c310
feat: Supports launching multiple monolithic instances, load-balanced by nginx, requiring only MongoDB and Redis at a minimum (#3759)
* fix: performance issues with Kafka caused by encapsulating the MQ interface

* fix: admin token in standalone mode

* fix: full id version

* fix: resolve deadlock in cache eviction and improve GetBatch implementation

* refactor: replace LongConn with ClientConn interface and simplify message handling

* refactor: replace LongConn with ClientConn interface and simplify message handling

* fix: seq use $setOnInsert for min_seq in conversation update

* feat: add error code for handled friend requests and improve error handling in friend operations

* refactor(msg): update regex pattern for conversationID to include a trailing colon

* refactor: streamline cache initialization and enhance queue engine configuration

* refactor: streamline cache initialization and enhance queue engine configuration

* feat: add RegisterIP to API config and implement Redis server registration

* feat(redis): implement standalone gateway registration with Redis

* chore: update openimsdk/tools dependency to v0.0.50-alpha.121

* fix: change timer to ticker for improved periodic execution

* refactor: replace Kafka topic configuration with mqbuild constants for improved readability

* feat(redis): implement Redis-based locking mechanism for cron tasks
2026-07-03 10:28:06 +00:00

64 lines
1.8 KiB
Go

package config
import (
"os"
"path/filepath"
"reflect"
"strings"
"github.com/mitchellh/mapstructure"
"github.com/spf13/viper"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/utils/runtimeenv"
)
func Load(configDirectory string, configFileName string, envPrefix string, config any) error {
if runtimeenv.RuntimeEnvironment() == KUBERNETES {
mountPath := os.Getenv(MountConfigFilePath)
if mountPath == "" {
return errs.ErrArgs.WrapMsg(MountConfigFilePath + " env is empty")
}
return loadConfig(filepath.Join(mountPath, configFileName), envPrefix, config)
}
return loadConfig(filepath.Join(configDirectory, configFileName), envPrefix, config)
}
func loadConfig(path string, envPrefix string, config any) error {
v := viper.New()
v.SetConfigFile(path)
v.SetEnvPrefix(envPrefix)
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
if err := v.ReadInConfig(); err != nil {
return errs.WrapMsg(err, "failed to read config file", "path", path, "envPrefix", envPrefix)
}
if err := v.Unmarshal(config, ApplyDecoderConfig); err != nil {
return errs.WrapMsg(err, "failed to unmarshal config", "path", path, "envPrefix", envPrefix)
}
return nil
}
func ApplyDecoderConfig(config *mapstructure.DecoderConfig) {
config.TagName = StructTagName
config.DecodeHook = mapstructure.ComposeDecodeHookFunc(
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
stringToEngineSelectorHookFunc(),
)
}
func stringToEngineSelectorHookFunc() mapstructure.DecodeHookFuncType {
engineSelectorType := reflect.TypeOf(EngineSelector{})
return func(from reflect.Type, to reflect.Type, data any) (any, error) {
if to != engineSelectorType || from.Kind() != reflect.String {
return data, nil
}
return EngineSelector{Engine: data.(string)}, nil
}
}