-
Notifications
You must be signed in to change notification settings - Fork 135
IGNITE-14180 Configuration notifications. #76
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
Conversation
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
# Conflicts: # modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
| if (valueAnnotation != null) { | ||
| ClassName dynPropClass = ClassName.get(DynamicProperty.class); | ||
| ClassName confValueClass = ClassName.get(ConfigurationValue.class); | ||
| ClassName dynPropClass = ClassName.get("org.apache.ignite.configuration.internal", "DynamicProperty"); |
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.
Just being curious: why did you change this?
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.
Because I kept getting "NoClassDefFoundError" from that damn ITProcessorTest and this turned out to be the only way to fix it.
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 deserves a comment
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.
Ok
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.
accidentallyget -- typo
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.
Done
| } | ||
| }); | ||
|
|
||
| return CompletableFuture.allOf(futures.stream().map(listenerFut -> listenerFut.handle((res, throwable) -> { |
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.
Please extract the inner stream into a variable, it's hard to read otherwise
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.
Sure
| /** Annotation classes mapped to validator objects. */ | ||
| private Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators = new HashMap<>(); | ||
|
|
||
| /** */ |
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.
This should be a proper javadoc)
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.
Done
| @FunctionalInterface | ||
| public interface Notificator { | ||
| /** */ | ||
| @NotNull CompletableFuture<?> notify(SuperRoot oldRoot, SuperRoot newRoot, long storageRevision); |
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.
why not CompletableFuture<Void>?
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.
Honestly, I see no difference between these two. Should I change it?
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 that the difference is that CompletableFuture<Void> explicitly states that there's no value inside it, while CompletableFuture<?> is closer to CompletableFuture<Object>
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.
Ok, that makes sense. That's my laziness.
| /** Constructor. */ | ||
| public ConfigurationChanger(RootKey<?, ?>... rootKeys) { | ||
| /** | ||
| * @param notificator Closure to execute when update forom storage is received. |
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.
| * @param notificator Closure to execute when update forom storage is received. | |
| * @param notificator Closure to execute when update from the storage is received. |
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.
Done
| InnerNode newInnerNode, | ||
| DynamicConfiguration<InnerNode, ?, ?> cfgNode, | ||
| long storageRevision, | ||
| List<CompletableFuture<?>> futures |
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.
Can we make it a return value?
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 mean the list? It's more convenient to accumulate values this way I think, method is recursive and I wouldn't want to merge collections every time.
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 can create a public method that will return a List, while inside you can call some recursive private methods that will populate this list. This is effectively the same approach, but I think it will make the API cleaner
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.
So basically you mean that I should make this one private and create new public method that will return list, right? Ok, not a problem
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.
exactly
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.
We call this method from outside several times so I'll leave it with list parameter.
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.
ok!
| * Called on property value update. | ||
| * | ||
| * @param ctx Notification context. | ||
| * @return Future that signifies end of listener execution. Can be {@code null}. |
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.
What does null mean in this context?
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.
null is equivalent to completed future. I'll clarify it in the comment.
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.
Can we return a completed future instead?
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.
That's for convenience, people will implement this method and return completed future in most cases, why not allow them to return null instead?
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.
Writing Future.completedFuture is not that hard, while dealing with both nulls and normal futures looks confusing and not a very clean design. Of course, that's mostly subjective.
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.
Ok, I fixed it
| void removeListener(ConfigurationStorageListener listener); | ||
|
|
||
| /** | ||
| * Notify storage that this specific revision was successfully handled and there's no necessity to repeat the same |
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.
| * Notify storage that this specific revision was successfully handled and there's no necessity to repeat the same | |
| * Notify storage that this specific revision was successfully handled and it is not necessary to repeat the same |
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.
Done
| } | ||
|
|
||
| /** | ||
| * Nullifies values in {@code newNode} that 100% match with corresponding values in {@code curNode}. |
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.
Sorry, I don't understand what you are trying to say here...
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.
Ok, I will try my best to rephrase it))
| import static org.apache.ignite.configuration.internal.util.ConfigurationUtil.namedListNodeVisitor; | ||
|
|
||
| /** */ | ||
| public class ConfigurationNotificationsUtil { |
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.
why do you need this class? It's only used in ConfigurationRegistry
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.
Because methods in it are big and I don't want to have too much extra stuff in ConfigurationRegistry
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
| private Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators = new HashMap<>(); | ||
|
|
||
| /** | ||
| * Closure interface to be used by configuration changer. Instance of this closur is passed into constructor and |
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.
| * Closure interface to be used by configuration changer. Instance of this closur is passed into constructor and | |
| * Closure interface to be used by configuration changer. An instance of this closure is passed into constructor and |
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.
Ok, thank you!
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java
Outdated
Show resolved
Hide resolved
modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java
Outdated
Show resolved
Hide resolved
modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java
Outdated
Show resolved
Hide resolved
|
|
||
| try { | ||
| change(defaultsNode, storageType).get(); | ||
| change0(defaultsNode, storageInstances.get(storageType)).get(); |
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.
It's interesting that you've decided to remove the method with the name change and not change0 =)
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'll rename it in the future)
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.
why not now?
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.
Ok
modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java
Outdated
Show resolved
Hide resolved
...iguration/src/main/java/org/apache/ignite/configuration/internal/util/ConfigurationUtil.java
Outdated
Show resolved
Hide resolved
...iguration/src/main/java/org/apache/ignite/configuration/internal/util/ConfigurationUtil.java
Outdated
Show resolved
Hide resolved
…ation/ConfigurationChanger.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
…ation/ConfigurationChanger.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
…ation/ConfigurationChanger.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
…ation/ConfigurationChanger.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
…ation/internal/util/ConfigurationUtil.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
…ation/internal/util/ConfigurationUtil.java Co-authored-by: Alexander Polovtcev <alex.polovtcev@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov <bessonov.ip@gmail.com>
Signed-off-by: ibessonov bessonov.ip@gmail.com