notify event on remote config changed

This commit is contained in:
yoyofx 2021-07-29 19:30:03 +08:00
parent a67dc7b1ca
commit 887c8e78ea
4 changed files with 73 additions and 22 deletions

View File

@ -1,6 +1,7 @@
package nacos_viper_remote
import (
"bytes"
"fmt"
"github.com/spf13/viper"
)
@ -16,9 +17,9 @@ func NewRemoteProvider(configType string) *ViperRemoteProvider {
configSet: "yoyogo.cloud.discovery.metadata"}
}
func (provider *ViperRemoteProvider) GetProvider(runtime_viper *viper.Viper) *viper.Viper {
func (provider *ViperRemoteProvider) GetProvider(runtimeViper *viper.Viper) *viper.Viper {
var option *Option
err := runtime_viper.Sub(provider.configSet).Unmarshal(&option)
err := runtimeViper.Sub(provider.configSet).Unmarshal(&option)
if err != nil {
panic(err)
return nil
@ -32,7 +33,7 @@ func (provider *ViperRemoteProvider) GetProvider(runtime_viper *viper.Viper) *vi
remote_viper.SetConfigType(provider.configType)
err = remote_viper.ReadRemoteConfig()
if err == nil {
err = remote_viper.WatchRemoteConfigOnChannel()
//err = remote_viper.WatchRemoteConfigOnChannel()
if err == nil {
fmt.Println("used remote viper")
return remote_viper
@ -40,5 +41,22 @@ func (provider *ViperRemoteProvider) GetProvider(runtime_viper *viper.Viper) *vi
} else {
panic(err)
}
return runtime_viper
return runtimeViper
}
func (provider *ViperRemoteProvider) WatchRemoteConfigOnChannel(remoteViper *viper.Viper) <-chan bool {
updater := make(chan bool)
respChan, _ := viper.RemoteConfig.WatchChannel(DefaultRemoteProvider())
go func(rc <-chan *viper.RemoteResponse) {
for {
b := <-rc
reader := bytes.NewReader(b.Value)
_ = remoteViper.ReadConfig(reader)
// configuration on changed
updater <- true
}
}(respChan)
return updater
}

View File

@ -32,14 +32,21 @@ func main() {
remote_viper := viper.New()
err := remote_viper.AddRemoteProvider("nacos", "localhost", "")
remote_viper.SetConfigType("yaml")
err = remote_viper.ReadRemoteConfig()
if err == nil {
err = remote_viper.WatchRemoteConfigOnChannel()
if err == nil {
config_viper = remote_viper
fmt.Println("used remote viper")
}
config_viper = remote_viper
fmt.Println("used remote viper")
provider := remote.NewRemoteProvider("yaml")
respChan := provider.WatchRemoteConfigOnChannel(config_viper)
go func(rc <-chan bool) {
for {
<-rc
fmt.Printf("remote async: %s", config_viper.GetString("yoyogo.application.name"))
}
}(respChan)
}
appName := config_viper.GetString("yoyogo.application.name")
@ -50,7 +57,7 @@ func main() {
for {
time.Sleep(time.Second * 30) // delay after each request
appName = config_viper.GetString("yoyogo.application.name")
fmt.Println(appName)
fmt.Println("sync:" + appName)
}
}()

28
nacosprovider.go Normal file
View File

@ -0,0 +1,28 @@
package nacos_viper_remote
type nacosRemoteProvider struct {
provider string
endpoint string
path string
secretKeyring string
}
func DefaultRemoteProvider() *nacosRemoteProvider {
return &nacosRemoteProvider{provider: "nacos", endpoint: "localhost", path: "", secretKeyring: ""}
}
func (rp nacosRemoteProvider) Provider() string {
return rp.provider
}
func (rp nacosRemoteProvider) Endpoint() string {
return rp.endpoint
}
func (rp nacosRemoteProvider) Path() string {
return rp.path
}
func (rp nacosRemoteProvider) SecretKeyring() string {
return rp.secretKeyring
}

View File

@ -7,17 +7,20 @@ import (
"io"
)
var nacosOptions = &Option{}
//var nacosOptions = &Option{}
func SetOptions(option *Option) {
nacosOptions = option
manager, _ := NewNacosConfigManager(option)
viper.SupportedRemoteProviders = []string{"nacos"}
viper.RemoteConfig = &remoteConfigProvider{ConfigManager: manager}
}
type remoteConfigProvider struct {
ConfigManager *nacosConfigManager
}
func (rc *remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) {
cmt, err := getConfigManager(rp)
cmt, err := rc.getConfigManager(rp)
if err != nil {
return nil, err
}
@ -37,7 +40,7 @@ func (rc *remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error
}
func (rc *remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
cmt, err := getConfigManager(rp)
cmt, err := rc.getConfigManager(rp)
if err != nil {
return nil, nil
}
@ -52,15 +55,10 @@ func (rc *remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *v
return nil, nil
}
func getConfigManager(rp viper.RemoteProvider) (interface{}, error) {
func (rc *remoteConfigProvider) getConfigManager(rp viper.RemoteProvider) (interface{}, error) {
if rp.Provider() == "nacos" {
return NewNacosConfigManager(nacosOptions)
return rc.ConfigManager, nil
} else {
return nil, errors.New("The Nacos configuration manager is not supported!")
}
}
func init() {
viper.SupportedRemoteProviders = []string{"nacos"}
viper.RemoteConfig = &remoteConfigProvider{}
}