Skip to content

Commit

Permalink
feat: Add enable config center button && fix: grpc connection leakage (
Browse files Browse the repository at this point in the history
…#621)

* feat: config center

* feat: config center

* feat: config etcd conn

* fix: call err

* fix: config
  • Loading branch information
icey-yu authored and OpenIM-Robot committed Jan 9, 2025
1 parent 89ad33b commit 6e9d420
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 79 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/gomake v0.0.14-alpha.5
github.com/openimsdk/protocol v0.0.72
github.com/openimsdk/tools v0.0.50-alpha.56
github.com/openimsdk/tools v0.0.50-alpha.64
github.com/redis/go-redis/v9 v9.5.1
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
github.com/xuri/excelize/v2 v2.8.0
go.etcd.io/etcd/client/v3 v3.5.13
go.mongodb.org/mongo-driver v1.14.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
)
Expand Down Expand Up @@ -119,7 +120,6 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.3.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCF
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.72 h1:K+vslwaR7lDXyBzb07UuEQITaqsgighz7NyXVIWsu6A=
github.com/openimsdk/protocol v0.0.72/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/tools v0.0.50-alpha.56 h1:22y0s3IPqgUYrO+r93H8Iq2oW71D5SUe88lkA0asEhU=
github.com/openimsdk/tools v0.0.50-alpha.56/go.mod h1:muCtxguNJv8lFwLei27UASu2Nvg4ERSeN0R4K5tivk0=
github.com/openimsdk/tools v0.0.50-alpha.64 h1:KmtE8V2K8atQJJg1xq2ySSrPQyf8ldwk8fw6jRnsxCw=
github.com/openimsdk/tools v0.0.50-alpha.64/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
Expand Down
79 changes: 40 additions & 39 deletions internal/api/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ func (o *Api) AdminUpdateInfo(c *gin.Context) {
}

func (o *Api) AdminInfo(c *gin.Context) {
a2r.Call(admin.AdminClient.GetAdminInfo, o.adminClient, c)
a2r.Call(c, admin.AdminClient.GetAdminInfo, o.adminClient)
}

func (o *Api) ChangeAdminPassword(c *gin.Context) {
a2r.Call(admin.AdminClient.ChangeAdminPassword, o.adminClient, c)
a2r.Call(c, admin.AdminClient.ChangeAdminPassword, o.adminClient)
}

func (o *Api) AddAdminAccount(c *gin.Context) {
a2r.Call(admin.AdminClient.AddAdminAccount, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddAdminAccount, o.adminClient)
}

func (o *Api) AddUserAccount(c *gin.Context) {
Expand Down Expand Up @@ -164,27 +164,27 @@ func (o *Api) AddUserAccount(c *gin.Context) {
}

func (o *Api) DelAdminAccount(c *gin.Context) {
a2r.Call(admin.AdminClient.DelAdminAccount, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelAdminAccount, o.adminClient)
}

func (o *Api) SearchAdminAccount(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchAdminAccount, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchAdminAccount, o.adminClient)
}

func (o *Api) AddDefaultFriend(c *gin.Context) {
a2r.Call(admin.AdminClient.AddDefaultFriend, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddDefaultFriend, o.adminClient)
}

func (o *Api) DelDefaultFriend(c *gin.Context) {
a2r.Call(admin.AdminClient.DelDefaultFriend, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelDefaultFriend, o.adminClient)
}

func (o *Api) SearchDefaultFriend(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchDefaultFriend, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchDefaultFriend, o.adminClient)
}

func (o *Api) FindDefaultFriend(c *gin.Context) {
a2r.Call(admin.AdminClient.FindDefaultFriend, o.adminClient, c)
a2r.Call(c, admin.AdminClient.FindDefaultFriend, o.adminClient)
}

func (o *Api) AddDefaultGroup(c *gin.Context) {
Expand Down Expand Up @@ -218,11 +218,11 @@ func (o *Api) AddDefaultGroup(c *gin.Context) {
}

func (o *Api) DelDefaultGroup(c *gin.Context) {
a2r.Call(admin.AdminClient.DelDefaultGroup, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelDefaultGroup, o.adminClient)
}

func (o *Api) FindDefaultGroup(c *gin.Context) {
a2r.Call(admin.AdminClient.FindDefaultGroup, o.adminClient, c)
a2r.Call(c, admin.AdminClient.FindDefaultGroup, o.adminClient)
}

func (o *Api) SearchDefaultGroup(c *gin.Context) {
Expand Down Expand Up @@ -269,47 +269,47 @@ func (o *Api) SearchDefaultGroup(c *gin.Context) {
}

func (o *Api) AddInvitationCode(c *gin.Context) {
a2r.Call(admin.AdminClient.AddInvitationCode, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddInvitationCode, o.adminClient)
}

func (o *Api) GenInvitationCode(c *gin.Context) {
a2r.Call(admin.AdminClient.GenInvitationCode, o.adminClient, c)
a2r.Call(c, admin.AdminClient.GenInvitationCode, o.adminClient)
}

func (o *Api) DelInvitationCode(c *gin.Context) {
a2r.Call(admin.AdminClient.DelInvitationCode, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelInvitationCode, o.adminClient)
}

func (o *Api) SearchInvitationCode(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchInvitationCode, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchInvitationCode, o.adminClient)
}

func (o *Api) AddUserIPLimitLogin(c *gin.Context) {
a2r.Call(admin.AdminClient.AddUserIPLimitLogin, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddUserIPLimitLogin, o.adminClient)
}

func (o *Api) SearchUserIPLimitLogin(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchUserIPLimitLogin, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchUserIPLimitLogin, o.adminClient)
}

func (o *Api) DelUserIPLimitLogin(c *gin.Context) {
a2r.Call(admin.AdminClient.DelUserIPLimitLogin, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelUserIPLimitLogin, o.adminClient)
}

func (o *Api) SearchIPForbidden(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchIPForbidden, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchIPForbidden, o.adminClient)
}

func (o *Api) AddIPForbidden(c *gin.Context) {
a2r.Call(admin.AdminClient.AddIPForbidden, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddIPForbidden, o.adminClient)
}

func (o *Api) DelIPForbidden(c *gin.Context) {
a2r.Call(admin.AdminClient.DelIPForbidden, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelIPForbidden, o.adminClient)
}

func (o *Api) ParseToken(c *gin.Context) {
a2r.Call(admin.AdminClient.ParseToken, o.adminClient, c)
a2r.Call(c, admin.AdminClient.ParseToken, o.adminClient)
}

func (o *Api) BlockUser(c *gin.Context) {
Expand Down Expand Up @@ -337,43 +337,43 @@ func (o *Api) BlockUser(c *gin.Context) {
}

func (o *Api) UnblockUser(c *gin.Context) {
a2r.Call(admin.AdminClient.UnblockUser, o.adminClient, c)
a2r.Call(c, admin.AdminClient.UnblockUser, o.adminClient)
}

func (o *Api) SearchBlockUser(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchBlockUser, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchBlockUser, o.adminClient)
}

func (o *Api) SetClientConfig(c *gin.Context) {
a2r.Call(admin.AdminClient.SetClientConfig, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SetClientConfig, o.adminClient)
}

func (o *Api) DelClientConfig(c *gin.Context) {
a2r.Call(admin.AdminClient.DelClientConfig, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelClientConfig, o.adminClient)
}

func (o *Api) GetClientConfig(c *gin.Context) {
a2r.Call(admin.AdminClient.GetClientConfig, o.adminClient, c)
a2r.Call(c, admin.AdminClient.GetClientConfig, o.adminClient)
}

func (o *Api) AddApplet(c *gin.Context) {
a2r.Call(admin.AdminClient.AddApplet, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddApplet, o.adminClient)
}

func (o *Api) DelApplet(c *gin.Context) {
a2r.Call(admin.AdminClient.DelApplet, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DelApplet, o.adminClient)
}

func (o *Api) UpdateApplet(c *gin.Context) {
a2r.Call(admin.AdminClient.UpdateApplet, o.adminClient, c)
a2r.Call(c, admin.AdminClient.UpdateApplet, o.adminClient)
}

func (o *Api) SearchApplet(c *gin.Context) {
a2r.Call(admin.AdminClient.SearchApplet, o.adminClient, c)
a2r.Call(c, admin.AdminClient.SearchApplet, o.adminClient)
}

func (o *Api) LoginUserCount(c *gin.Context) {
a2r.Call(chat.ChatClient.UserLoginCount, o.chatClient, c)
a2r.Call(c, chat.ChatClient.UserLoginCount, o.chatClient)
}

func (o *Api) NewUserCount(c *gin.Context) {
Expand Down Expand Up @@ -502,6 +502,7 @@ func (o *Api) xlsxBirth(s string) time.Time {
separator = b
}
}

arr := strings.Split(s, string([]byte{separator}))
if len(arr) != 3 {
return time.Now()
Expand Down Expand Up @@ -560,29 +561,29 @@ func (o *Api) BatchImportTemplate(c *gin.Context) {
}

func (o *Api) SetAllowRegister(c *gin.Context) {
a2r.Call(chat.ChatClient.SetAllowRegister, o.chatClient, c)
a2r.Call(c, chat.ChatClient.SetAllowRegister, o.chatClient)
}

func (o *Api) GetAllowRegister(c *gin.Context) {
a2r.Call(chat.ChatClient.GetAllowRegister, o.chatClient, c)
a2r.Call(c, chat.ChatClient.GetAllowRegister, o.chatClient)
}

func (o *Api) LatestApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.LatestApplicationVersion, o.adminClient, c)
a2r.Call(c, admin.AdminClient.LatestApplicationVersion, o.adminClient)
}

func (o *Api) PageApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.PageApplicationVersion, o.adminClient, c)
a2r.Call(c, admin.AdminClient.PageApplicationVersion, o.adminClient)
}

func (o *Api) AddApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.AddApplicationVersion, o.adminClient, c)
a2r.Call(c, admin.AdminClient.AddApplicationVersion, o.adminClient)
}

func (o *Api) UpdateApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.UpdateApplicationVersion, o.adminClient, c)
a2r.Call(c, admin.AdminClient.UpdateApplicationVersion, o.adminClient)
}

func (o *Api) DeleteApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.DeleteApplicationVersion, o.adminClient, c)
a2r.Call(c, admin.AdminClient.DeleteApplicationVersion, o.adminClient)
}
78 changes: 67 additions & 11 deletions internal/api/admin/config_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
)

const (
// wait for Restart http call return
waitHttp = time.Millisecond * 200
)

type ConfigManager struct {
config *config.AllConfig
client *clientv3.Client
Expand Down Expand Up @@ -126,16 +131,19 @@ func compareAndSave[T any](c *gin.Context, old any, req *apistruct.SetConfigReq,
}

func (cm *ConfigManager) ResetConfig(c *gin.Context) {
go cm.resetConfig(c)
go func() {
if err := cm.resetConfig(c, true); err != nil {
log.ZError(c, "reset config err", err)
}
}()
apiresp.GinSuccess(c, nil)
}

func (cm *ConfigManager) resetConfig(c *gin.Context) {
func (cm *ConfigManager) resetConfig(c *gin.Context, checkChange bool, ops ...clientv3.Op) error {
txn := cm.client.Txn(c)
type initConf struct {
old any
new any
isChanged bool
old any
new any
}
configMap := map[string]*initConf{
config.DiscoveryConfigFileName: {old: &cm.config.Discovery, new: new(config.Discovery)},
Expand All @@ -162,13 +170,12 @@ func (cm *ConfigManager) resetConfig(c *gin.Context) {
log.ZError(c, "load config failed", err)
continue
}
v.isChanged = reflect.DeepEqual(v.old, v.new)
if !v.isChanged {
equal := reflect.DeepEqual(v.old, v.new)
if !checkChange || !equal {
changedKeys = append(changedKeys, k)
}
}

ops := make([]clientv3.Op, 0)
for _, k := range changedKeys {
data, err := json.Marshal(configMap[k].new)
if err != nil {
Expand All @@ -181,10 +188,10 @@ func (cm *ConfigManager) resetConfig(c *gin.Context) {
txn.Then(ops...)
_, err := txn.Commit()
if err != nil {
log.ZError(c, "commit etcd txn failed", err)
return
return errs.WrapMsg(err, "commit etcd txn failed")
}
}
return nil
}

func (cm *ConfigManager) Restart(c *gin.Context) {
Expand All @@ -193,10 +200,59 @@ func (cm *ConfigManager) Restart(c *gin.Context) {
}

func (cm *ConfigManager) restart(c *gin.Context) {
time.Sleep(time.Millisecond * 200) // wait for Restart http call return
time.Sleep(waitHttp) // wait for Restart http call return
t := time.Now().Unix()
_, err := cm.client.Put(c, etcd.BuildKey(etcd.RestartKey), strconv.Itoa(int(t)))
if err != nil {
log.ZError(c, "restart etcd put key failed", err)
}
}

func (cm *ConfigManager) SetEnableConfigManager(c *gin.Context) {
var req apistruct.SetEnableConfigManagerReq
if err := c.BindJSON(&req); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
var enableStr string
if req.Enable {
enableStr = etcd.Enable
} else {
enableStr = etcd.Disable
}
resp, err := cm.client.Get(c, etcd.BuildKey(etcd.EnableConfigCenterKey))
if err != nil {
apiresp.GinError(c, errs.WrapMsg(err, "getEnableConfigManager failed"))
return
}
if !(resp.Count > 0 && string(resp.Kvs[0].Value) == etcd.Enable) && req.Enable {
go func() {
time.Sleep(waitHttp) // wait for Restart http call return
err := cm.resetConfig(c, false, clientv3.OpPut(etcd.BuildKey(etcd.EnableConfigCenterKey), enableStr))
if err != nil {
log.ZError(c, "writeAllConfig failed", err)
}
}()
} else {
_, err = cm.client.Put(c, etcd.BuildKey(etcd.EnableConfigCenterKey), enableStr)
if err != nil {
apiresp.GinError(c, errs.WrapMsg(err, "setEnableConfigManager failed"))
return
}
}

apiresp.GinSuccess(c, nil)
}

func (cm *ConfigManager) GetEnableConfigManager(c *gin.Context) {
resp, err := cm.client.Get(c, etcd.BuildKey(etcd.EnableConfigCenterKey))
if err != nil {
apiresp.GinError(c, errs.WrapMsg(err, "getEnableConfigManager failed"))
return
}
var enable bool
if resp.Count > 0 && string(resp.Kvs[0].Value) == etcd.Enable {
enable = true
}
apiresp.GinSuccess(c, &apistruct.GetEnableConfigManagerResp{Enable: enable})
}
Loading

0 comments on commit 6e9d420

Please sign in to comment.