Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
thythm
ribbon
提交
3849d851
R
ribbon
项目概览
thythm
/
ribbon
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
ribbon
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
3849d851
编写于
5月 18, 2019
作者:
E
elandau
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
config: Fix excessive change notifications
上级
2a13e39c
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
67 addition
and
44 deletion
+67
-44
ribbon-archaius/src/main/java/com/netflix/client/config/ArchaiusPropertyResolver.java
...a/com/netflix/client/config/ArchaiusPropertyResolver.java
+24
-8
ribbon-core/src/main/java/com/netflix/client/config/ReloadableClientConfig.java
...ava/com/netflix/client/config/ReloadableClientConfig.java
+41
-36
ribbon-core/src/test/resources/log4j.properties
ribbon-core/src/test/resources/log4j.properties
+2
-0
未找到文件。
ribbon-archaius/src/main/java/com/netflix/client/config/ArchaiusPropertyResolver.java
浏览文件 @
3849d851
...
...
@@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
import
java.util.Arrays
;
import
java.util.Optional
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.concurrent.TimeUnit
;
import
java.util.function.BiConsumer
;
import
java.util.stream.Collectors
;
...
...
@@ -18,9 +19,27 @@ public class ArchaiusPropertyResolver implements PropertyResolver {
public
static
final
ArchaiusPropertyResolver
INSTANCE
=
new
ArchaiusPropertyResolver
();
private
final
AbstractConfiguration
config
;
private
final
CopyOnWriteArrayList
<
Runnable
>
actions
=
new
CopyOnWriteArrayList
<>();
private
ArchaiusPropertyResolver
()
{
this
.
config
=
ConfigurationManager
.
getConfigInstance
();
ConfigurationManager
.
getConfigInstance
().
addConfigurationListener
(
new
ConfigurationListener
()
{
@Override
public
void
configurationChanged
(
ConfigurationEvent
event
)
{
if
(!
event
.
isBeforeUpdate
())
{
actions
.
forEach
(
ArchaiusPropertyResolver:
:
invokeAction
);
}
}
});
}
private
static
void
invokeAction
(
Runnable
action
)
{
try
{
action
.
run
();
}
catch
(
Exception
e
)
{
LOG
.
info
(
"Failed to invoke action"
,
e
);
}
}
@Override
...
...
@@ -66,13 +85,10 @@ public class ArchaiusPropertyResolver implements PropertyResolver {
@Override
public
void
onChange
(
Runnable
action
)
{
ConfigurationManager
.
getConfigInstance
().
addConfigurationListener
(
new
ConfigurationListener
()
{
@Override
public
void
configurationChanged
(
ConfigurationEvent
event
)
{
if
(!
event
.
isBeforeUpdate
())
{
action
.
run
();
}
}
});
actions
.
add
(
action
);
}
public
int
getActionCount
()
{
return
actions
.
size
();
}
}
ribbon-core/src/main/java/com/netflix/client/config/ReloadableClientConfig.java
浏览文件 @
3849d851
package
com.netflix.client.config
;
import
com.google.common.base.MoreObjects
;
import
com.google.common.base.Preconditions
;
import
org.apache.commons.lang.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -40,7 +39,7 @@ public abstract class ReloadableClientConfig implements IClientConfig {
private
static
final
String
DEFAULT_NAMESPACE
=
"ribbon"
;
// Map of raw property names (without namespace or client) to values set via code
private
final
Map
<
String
,
Object
>
default
Properties
=
new
HashMap
<>();
private
final
Map
<
String
,
Object
>
internal
Properties
=
new
HashMap
<>();
// Map of all seen dynamic properties. This map will hold on properties requested with the exception of
// those returned from getGlobalProperty().
...
...
@@ -60,17 +59,18 @@ public abstract class ReloadableClientConfig implements IClientConfig {
private
boolean
isDynamic
;
private
boolean
isLoaded
=
false
;
protected
ReloadableClientConfig
(
PropertyResolver
resolver
)
{
this
(
resolver
,
DEFAULT_CLIENT_NAME
)
;
this
.
clientName
=
DEFAULT_CLIENT_NAME
;
this
.
isDynamic
=
false
;
this
.
resolver
=
resolver
;
}
protected
ReloadableClientConfig
(
PropertyResolver
resolver
,
String
clientName
)
{
this
.
clientName
=
clientName
;
this
.
isDynamic
=
true
;
this
.
resolver
=
resolver
;
resolver
.
onChange
(
this
::
reload
);
}
protected
PropertyResolver
getPropertyResolver
()
{
...
...
@@ -85,6 +85,10 @@ public abstract class ReloadableClientConfig implements IClientConfig {
cachedToString
=
null
;
}
/**
* @deprecated Use {@link #loadProperties(String)}
*/
@Deprecated
public
void
setClientName
(
String
clientName
){
this
.
clientName
=
clientName
;
}
...
...
@@ -106,6 +110,12 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
public
void
loadProperties
(
String
clientName
)
{
Preconditions
.
checkState
(
isLoaded
==
false
,
"Config '{}' can only be loaded once"
,
clientName
);
if
(!
isLoaded
)
{
this
.
isLoaded
=
true
;
resolver
.
onChange
(
this
::
reload
);
}
this
.
isDynamic
=
true
;
this
.
clientName
=
clientName
;
loadDefaultValues
();
...
...
@@ -119,19 +129,12 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
public
final
Map
<
String
,
Object
>
getProperties
()
{
Map
<
String
,
Object
>
result
=
new
HashMap
<>(
dynamicProperties
.
size
());
dynamicProperties
.
forEach
((
key
,
prop
)
->
prop
.
get
().
ifPresent
(
value
->
result
.
put
(
key
.
key
(),
String
.
valueOf
(
value
)))
);
LOG
.
info
(
result
.
toString
());
return
result
;
return
Collections
.
unmodifiableMap
(
internalProperties
);
}
@Override
public
void
forEachDefault
(
BiConsumer
<
IClientConfigKey
<?>,
Object
>
consumer
)
{
dynamicProperties
.
forEach
((
key
,
value
)
->
consumer
.
accept
(
key
,
default
Properties
.
get
(
key
.
key
())));
dynamicProperties
.
forEach
((
key
,
value
)
->
consumer
.
accept
(
key
,
internal
Properties
.
get
(
key
.
key
())));
}
@Override
...
...
@@ -139,7 +142,7 @@ public abstract class ReloadableClientConfig implements IClientConfig {
dynamicProperties
.
forEach
((
key
,
value
)
->
consumer
.
accept
(
key
,
value
.
get
().
orElse
(
null
)));
}
private
<
T
>
ReloadableProperty
<
T
>
createProperty
(
final
Supplier
<
Optional
<
T
>>
valueSupplier
,
final
Supplier
<
T
>
defaultSupplier
,
final
boolean
isDynamic
)
{
private
<
T
>
ReloadableProperty
<
T
>
createProperty
(
final
Supplier
<
Optional
<
T
>>
valueSupplier
,
final
Supplier
<
T
>
defaultSupplier
)
{
Preconditions
.
checkNotNull
(
valueSupplier
,
"defaultValueSupplier cannot be null"
);
return
new
ReloadableProperty
<
T
>()
{
...
...
@@ -189,11 +192,15 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
public
final
<
T
>
T
get
(
IClientConfigKey
<
T
>
key
)
{
return
getInternal
(
key
).
get
().
orElse
(
null
);
if
(
isLoaded
)
{
return
getOrCreateProperty
(
key
).
get
().
orElse
(
null
);
}
else
{
return
getIfSet
(
key
).
orElse
(
null
);
}
}
p
ublic
final
<
T
>
ReloadableProperty
<
T
>
getInternal
(
IClientConfigKey
<
T
>
key
)
{
return
(
ReloadableProperty
<
T
>)
dynamicProperties
.
computeIfAbsent
(
key
,
ignore
->
getClientDynamicProperty
(
key
,
isDynamic
));
p
rivate
final
<
T
>
ReloadableProperty
<
T
>
getOrCreateProperty
(
IClientConfigKey
<
T
>
key
)
{
return
(
ReloadableProperty
<
T
>)
dynamicProperties
.
computeIfAbsent
(
key
,
ignore
->
getClientDynamicProperty
(
key
));
}
@Override
...
...
@@ -202,21 +209,19 @@ public abstract class ReloadableClientConfig implements IClientConfig {
return
(
Property
<
T
>)
dynamicProperties
.
computeIfAbsent
(
key
,
ignore
->
createProperty
(
()
->
resolver
.
get
(
key
.
key
(),
key
.
type
()),
key:
:
defaultValue
,
true
));
key:
:
defaultValue
));
}
interface
ReloadableProperty
<
T
>
extends
Property
<
T
>
{
void
refresh
();
}
private
<
T
>
ReloadableProperty
<
T
>
getClientDynamicProperty
(
IClientConfigKey
<
T
>
key
,
boolean
isDynamic
)
{
private
<
T
>
ReloadableProperty
<
T
>
getClientDynamicProperty
(
IClientConfigKey
<
T
>
key
)
{
LOG
.
debug
(
"Get dynamic property key={} ns={} client={}"
,
key
.
key
(),
getNameSpace
(),
clientName
);
return
createProperty
(
()
->
resolveFinalProperty
(
key
),
key:
:
defaultValue
,
isDynamic
);
key:
:
defaultValue
);
}
/**
...
...
@@ -257,7 +262,7 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
public
<
T
>
Optional
<
T
>
getIfSet
(
IClientConfigKey
<
T
>
key
)
{
return
Optional
.
ofNullable
(
default
Properties
.
get
(
key
.
key
()))
return
Optional
.
ofNullable
(
internal
Properties
.
get
(
key
.
key
()))
.
map
(
value
->
{
final
Class
<
T
>
type
=
key
.
type
();
// Unfortunately there's some legacy code setting string values for typed keys. Here are do our best to parse
...
...
@@ -299,23 +304,21 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
public
final
<
T
>
Property
<
T
>
getDynamicProperty
(
IClientConfigKey
<
T
>
key
)
{
return
getClientDynamicProperty
(
key
,
true
);
return
getClientDynamicProperty
(
key
);
}
@Override
public
<
T
>
Property
<
T
>
getScopedProperty
(
IClientConfigKey
<
T
>
key
)
{
return
(
Property
<
T
>)
dynamicProperties
.
computeIfAbsent
(
key
,
ignore
->
createProperty
(
()
->
resolverScopedProperty
(
key
),
key:
:
defaultValue
,
isDynamic
));
key:
:
defaultValue
));
}
@Override
public
<
T
>
Property
<
T
>
getPrefixMappedProperty
(
IClientConfigKey
<
T
>
key
)
{
return
(
Property
<
T
>)
dynamicProperties
.
computeIfAbsent
(
key
,
ignore
->
createProperty
(
getPrefixedMapPropertySupplier
(
key
),
key:
:
defaultValue
,
isDynamic
));
key:
:
defaultValue
));
}
private
<
T
>
Supplier
<
Optional
<
T
>>
getPrefixedMapPropertySupplier
(
IClientConfigKey
<
T
>
key
)
{
...
...
@@ -354,12 +357,14 @@ public abstract class ReloadableClientConfig implements IClientConfig {
Preconditions
.
checkArgument
(
key
!=
null
,
"key cannot be null"
);
// Treat nulls as deletes
if
(
value
==
null
)
{
default
Properties
.
remove
(
key
.
key
());
internal
Properties
.
remove
(
key
.
key
());
}
else
{
default
Properties
.
put
(
key
.
key
(),
value
);
internal
Properties
.
put
(
key
.
key
(),
value
);
}
getInternal
(
key
).
refresh
();
if
(
isLoaded
)
{
getOrCreateProperty
(
key
).
refresh
();
}
cachedToString
=
null
;
return
this
;
...
...
@@ -375,13 +380,13 @@ public abstract class ReloadableClientConfig implements IClientConfig {
@Override
@Deprecated
public
Object
getProperty
(
IClientConfigKey
key
)
{
return
get
Internal
(
key
).
get
().
orElse
(
null
);
return
get
(
key
);
}
@Override
@Deprecated
public
Object
getProperty
(
IClientConfigKey
key
,
Object
defaultVal
)
{
return
get
Internal
(
key
).
get
().
orElse
(
defaultVal
);
return
get
OrCreateProperty
(
key
).
get
().
orElse
(
defaultVal
);
}
@Override
...
...
@@ -413,7 +418,7 @@ public abstract class ReloadableClientConfig implements IClientConfig {
return
this
;
}
this
.
default
Properties
.
putAll
(
override
.
getProperties
());
this
.
internal
Properties
.
putAll
(
override
.
getProperties
());
reload
();
return
this
;
}
...
...
ribbon-core/src/test/resources/log4j.properties
浏览文件 @
3849d851
...
...
@@ -2,3 +2,5 @@ log4j.rootCategory=INFO,stdout
log4j.appender.stdout
=
org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout
=
org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern
=
%d %-5p %C:%L [%t] [%M] %m%n
log4j.logger.com.netflix.client.config
=
DEBUG
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录