Skip to content

Commit

Permalink
Merge pull request #302 from qdsordinarydream/fix/sync_supplement
Browse files Browse the repository at this point in the history
fix: 触发懒加载时,需要同步更新notify内容,更新component监听变更的ns
  • Loading branch information
mergify[bot] authored Mar 27, 2024
2 parents 8a27d76 + 2deb5ed commit a288a91
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 21 deletions.
32 changes: 27 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package agollo
import (
"container/list"
"errors"
"strings"

"github.com/apolloconfig/agollo/v4/agcache"
"github.com/apolloconfig/agollo/v4/agcache/memory"
Expand Down Expand Up @@ -158,19 +159,40 @@ func (c *internalClient) GetConfigAndInit(namespace string) *storage.Config {
return nil
}

config := c.cache.GetConfig(namespace)
cfg := c.cache.GetConfig(namespace)

if config == nil {
if cfg == nil {
//sync config
apolloConfig := syncApolloConfig.SyncWithNamespace(namespace, c.getAppConfig)
if apolloConfig != nil {
c.cache.UpdateApolloConfig(apolloConfig, c.getAppConfig)
c.SyncAndUpdate(namespace, apolloConfig)
}
}

cfg = c.cache.GetConfig(namespace)

return cfg
}

func (c *internalClient) SyncAndUpdate(namespace string, apolloConfig *config.ApolloConfig) {
// update appConfig only if namespace does not exist yet
namespaces := strings.Split(c.appConfig.NamespaceName, ",")
exists := false
for _, n := range namespaces {
if n == namespace {
exists = true
break
}
}
if !exists {
c.appConfig.NamespaceName += "," + namespace
}

config = c.cache.GetConfig(namespace)
// update notification
c.appConfig.GetNotificationsMap().UpdateNotify(namespace, 0)

return config
// update cache
c.cache.UpdateApolloConfig(apolloConfig, c.getAppConfig)
}

// GetConfigCache 根据namespace获取apollo配置的缓存
Expand Down
31 changes: 27 additions & 4 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,40 @@ func TestGetConfigAndInitValNotNil(t *testing.T) {
AppID: "testID",
NamespaceName: "testNotFound",
},
Configurations: map[string]interface{}{"testKey": "testValue"},
Configurations: map[string]interface{}{"testKey": "testUpdatedValue"},
}
})
defer patch.Reset()

client := createMockApolloConfig(120)
cf := client.GetConfig("testNotFound")
Assert(t, cf, NotNilVal())
// cache should be updated

// appConfig notificationsMap appConfig should be updated
Assert(t, client.appConfig.GetNotificationsMap().GetNotify("testNotFound"), Equal(int64(0)))

// cache should be updated with new configuration
Assert(t, client.cache.GetConfig("testNotFound"), NotNilVal())
Assert(t, client.cache.GetConfig("testNotFound").GetValue("testKey"), Equal("testValue"))
Assert(t, client.cache.GetConfig("testNotFound").GetValue("testKey"), Equal("testUpdatedValue"))
Assert(t, client.appConfig.NamespaceName, Equal("application,testNotFound"))
patch.Reset()

// second replace
patch1 := gomonkey.ApplyMethod(reflect.TypeOf(apc), "SyncWithNamespace", func(_ *remote.AbsApolloConfig, namespace string, appConfigFunc func() config.AppConfig) *config.ApolloConfig {
return &config.ApolloConfig{
ApolloConnConfig: config.ApolloConnConfig{
AppID: "testID",
NamespaceName: "testNotFound1",
},
Configurations: map[string]interface{}{"testKey": "testUpdatedValue"},
}
})
defer patch1.Reset()
client.appConfig.NamespaceName = "testNotFound1"
cf1 := client.GetConfig("testNotFound1")
Assert(t, cf1, NotNilVal())
Assert(t, client.cache.GetConfig("testNotFound1"), NotNilVal())
// appConfig namespace existed, should not be appended
Assert(t, client.appConfig.NamespaceName, Equal("testNotFound1"))
}

func TestGetConfigAndInitValNil(t *testing.T) {
Expand Down
18 changes: 18 additions & 0 deletions component/notify/componet_notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,21 @@ func getTestAppConfig() *config.AppConfig {
appConfig.Init()
return appConfig
}

func TestConfigComponent_SetAppConfig_UpdatesAppConfigCorrectly(t *testing.T) {
expectedAppConfig := getTestAppConfig()
c := &ConfigComponent{}
// set appConfigFunc
c.SetAppConfig(func() config.AppConfig {
return *expectedAppConfig
})

// appConfig should be equal
Assert(t, c.appConfigFunc(), Equal(*expectedAppConfig))

// appConfig value is be replaced
expectedAppConfig.AppID = "test1"
expectedAppConfig.NamespaceName = expectedAppConfig.NamespaceName + config.Comma + "abc"
Assert(t, c.appConfigFunc().AppID, Equal("test1"))
Assert(t, c.appConfigFunc().NamespaceName, Equal("application,abc"))
}
24 changes: 12 additions & 12 deletions env/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ import (

var (
defaultNotificationID = int64(-1)
comma = ","
Comma = ","
)

//File 读写配置文件
// File 读写配置文件
type File interface {
Load(fileName string, unmarshal func([]byte) (interface{}, error)) (interface{}, error)

Write(content interface{}, configPath string) error
}

//AppConfig 配置文件
// AppConfig 配置文件
type AppConfig struct {
AppID string `json:"appId"`
Cluster string `json:"cluster"`
Expand All @@ -56,27 +56,27 @@ type AppConfig struct {
currentConnApolloConfig *CurrentApolloConfig
}

//ServerInfo 服务器信息
// ServerInfo 服务器信息
type ServerInfo struct {
AppName string `json:"appName"`
InstanceID string `json:"instanceId"`
HomepageURL string `json:"homepageUrl"`
IsDown bool `json:"-"`
}

//GetIsBackupConfig whether backup config after fetch config from apollo
//false : no
//true : yes (default)
// GetIsBackupConfig whether backup config after fetch config from apollo
// false : no
// true : yes (default)
func (a *AppConfig) GetIsBackupConfig() bool {
return a.IsBackupConfig
}

//GetBackupConfigPath GetBackupConfigPath
// GetBackupConfigPath GetBackupConfigPath
func (a *AppConfig) GetBackupConfigPath() string {
return a.BackupConfigPath
}

//GetHost GetHost
// GetHost GetHost
func (a *AppConfig) GetHost() string {
u, err := url.Parse(a.IP)
if err != nil {
Expand Down Expand Up @@ -108,10 +108,10 @@ func (a *AppConfig) initAllNotifications(callback func(namespace string)) {
}
}

//SplitNamespaces 根据namespace字符串分割后,并执行callback函数
// SplitNamespaces 根据namespace字符串分割后,并执行callback函数
func SplitNamespaces(namespacesStr string, callback func(namespace string)) sync.Map {
namespaces := sync.Map{}
split := strings.Split(namespacesStr, comma)
split := strings.Split(namespacesStr, Comma)
for _, namespace := range split {
if callback != nil {
callback(namespace)
Expand All @@ -126,7 +126,7 @@ func (a *AppConfig) GetNotificationsMap() *notificationsMap {
return a.notificationsMap
}

//GetServicesConfigURL 获取服务器列表url
// GetServicesConfigURL 获取服务器列表url
func (a *AppConfig) GetServicesConfigURL() string {
return fmt.Sprintf("%sservices/config?appId=%s&ip=%s",
a.GetHost(),
Expand Down

0 comments on commit a288a91

Please sign in to comment.