-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(apollo-client): add method interestedChangedKeys to ConfigChangeEvent #3666
feat(apollo-client): add method interestedChangedKeys to ConfigChangeEvent #3666
Conversation
@@ -450,7 +468,7 @@ public void run() { | |||
String listenerName = listener.getClass().getName(); | |||
Transaction transaction = Tracer.newTransaction("Apollo.ConfigChangeListener", listenerName); | |||
try { | |||
listener.onChange(changeEvent); | |||
listener.onChange(resolve(listener, changeEvent)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about generate a new ConfigChangeEvent here?
Subclass's ConfigChangeEvent + resolved interestedChangedKeys ==> new ConfigChangeEvent
That will change the default behavior of subclass, but still keep compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we create a subclass of ConfigChangeEvent
, which contains the original config change event and the interested keys so that we don't need to create a new instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When subclasses of AbstractConfig
invoke method com.ctrip.framework.apollo.internals.AbstractConfig#fireConfigChange
, they don't know about any information of interestedKeys
because interestedKeys
are saved in AbstractConfig
.
If we create a subclass of ConfigChangeEvent
, when method com.ctrip.framework.apollo.internals.AbstractConfig#fireConfigChange
is invoking, we still need to create a new instance of subclass of ConfigChangeEvent
, because the listener need to get this instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are right, I was thinking we may use the composition
pattern to avoid create a lot of ConfigChangeEvent
instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change ConfigChangeEvent
to an abstract class?
public abstract class ConfigChangeEvent {
// content
}
Or create a new class AbstractConfigChangeEvent
,
public abstract class AbstractConfigChangeEvent {
public abstract Set<String> changedKeys();
public abstract Set<String> interestedChangedKeys();
public abstract ConfigChange getChange(String key);
public abstract boolean isChanged(String key);
public abstract String getNamespace();
}
then let ConfigChangeEvent
extends it?
public class ConfigChangeEvent extends AbstractConfigChangeEvent {
// ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My original idea was to create an abstract class or an interface, and then use composition
to wrap the original ConfigChangeEvent
into InterestedConfigChangeEvent. But the current implementation also looks good to me.
Codecov Report
@@ Coverage Diff @@
## master #3666 +/- ##
============================================
+ Coverage 50.32% 50.40% +0.07%
- Complexity 2374 2389 +15
============================================
Files 457 458 +1
Lines 14435 14472 +37
Branches 1457 1467 +10
============================================
+ Hits 7264 7294 +30
- Misses 6665 6674 +9
+ Partials 506 504 -2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the effort, basically I think it's fine. Please find some comments below.
BTW, I think we need to add some unit test for the new apis.
@@ -450,7 +468,7 @@ public void run() { | |||
String listenerName = listener.getClass().getName(); | |||
Transaction transaction = Tracer.newTransaction("Apollo.ConfigChangeListener", listenerName); | |||
try { | |||
listener.onChange(changeEvent); | |||
listener.onChange(resolve(listener, changeEvent)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we create a subclass of ConfigChangeEvent
, which contains the original config change event and the interested keys so that we don't need to create a new instance?
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java
Outdated
Show resolved
Hide resolved
apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChangeEvent.java
Outdated
Show resolved
Hide resolved
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
|
||
UnsupportedOperationConfig config = new UnsupportedOperationConfig(); | ||
config.addChangeListener(configChangeListener, Collections.singleton("key-nothing"), Collections.singleton(keyPrefix)); | ||
config.fireConfigChange(namespace, Collections.singletonMap(key, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest we add some irrelavent change here to check whether the interested keys logic works, e.g.
Map<String, ConfigChange> changes = new HashMap<>();
changes.put(key, new ConfigChange(namespace, key, "123", "456", PropertyChangeType.MODIFIED));
changes.put(anotherKey,
new ConfigChange(namespace, anotherKey, null, "someValue", PropertyChangeType.ADDED));
config.fireConfigChange(namespace, changes);
and then verify the changedKeys
and interestedChangedKeys
methods both work
ConfigChangeListener configChangeListener = spy(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
assertEquals(namespace, changeEvent.getNamespace());
assertEquals(2, changeEvent.changedKeys().size());
assertTrue(changeEvent.changedKeys().containsAll(Sets.newHashSet(key, anotherKey)));
assertEquals(1, changeEvent.interestedChangedKeys().size());
assertTrue(changeEvent.interestedChangedKeys().contains(key));
onChangeFuture.set(changeEvent);
}
});
as #3747 merged, please update changs log. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* | ||
* @return how many listener be fired | ||
*/ | ||
protected int fireConfigChange(final ConfigChangeEvent changeEvent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will it break the compability when change return type from void
to int
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will, since this method is protected, users may have overridden it
...o-client/src/main/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEvent.java
Show resolved
Hide resolved
changes.put("key1", new ConfigChange(namespace, "key1", null, "new-value", PropertyChangeType.ADDED)); | ||
ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(namespace, changes); | ||
|
||
assertEquals(0, abstractConfig.fireConfigChange(configChangeEvent)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can add a counter in this onChange method to test the times of invocation instead of changing the signature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
What's the purpose of this PR
Let user can get interestedChangedKeys through ConfigChangeEvent
Which issue(s) this PR fixes:
Fixes #3664
Brief changelog
resolve interestedChangedKeys in class AbstractConfig
Follow this checklist to help us incorporate your contribution quickly and easily:
mvn clean test
to make sure this pull request doesn't break anything.