-
Notifications
You must be signed in to change notification settings - Fork 6
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
Actor builder and updates #51
base: master
Are you sure you want to change the base?
Conversation
efd0198
to
b364e8a
Compare
84b691f
to
8b0bb52
Compare
The GraphiteSink was updated and the updated dependencies are in a separate PR. Please take a look at #52 before this. |
0788e13
to
bbcee86
Compare
Rebased off the updated dependencies. There are a few minor changes in here that are unrelated: minor refactor of emitter creation, changing to Java-based futures in Status actor. |
bbcee86
to
952af70
Compare
952af70
to
fd6921c
Compare
fd6921c
to
4afb2db
Compare
* | ||
* @author Brandon Arp (brandon dot arp at inscopemetrics dot com) | ||
*/ | ||
public class NonJoiningClusterJoiner extends UntypedActor { |
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.
Final?
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.
Oh you and your final classes.
* @param builder Builder to create the Props from | ||
* @return a new {@link Props} | ||
*/ | ||
private static Props props(final Builder builder) { |
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.
Builder is unused and the method is private
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.
The builder references the static method as the constructor for the Props. It looks similar to our other actors (except for the private part). I could make the props method public, but I'm not sure what that would really achieve.
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 guess my confusion here is that the builder argument is unused and since it's static it can't be overwritten. This is also not the standard builder pattern so it's not invoked reflectively. Still a little confused 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.
The Builder still references this method just like the constructor in the other Builders. The base builder takes a Function<Builder, Props>. Hence the need to have that signature.
* Public constructor. | ||
*/ | ||
public NonJoiningClusterJoiner() { | ||
LOGGER.info() |
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.
Shouldn't this go in the actor startup routine, not the ctor?
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.
Eh, I could put it on the onStart. I've tended toward the constuctor, though.
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.
Truth in advertising. It doesn't "start" on construction.
.log(); | ||
} | ||
|
||
@Override |
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.
Inherit doc
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.
Fixed.
super(NonJoiningClusterJoiner::props); | ||
} | ||
|
||
@Override |
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.
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.
Fixed.
.thenApply(CAST_MAPPER); | ||
stateFuture.whenComplete( | ||
(statusResponse, throwable) -> { | ||
final boolean healthy = _cluster.readView().self().status() == MemberStatus.up() && !_quarantined; |
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.
Objects.equal instead of ==
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.
Fixed
try { | ||
final Class<?> clazz = Class.forName(type); | ||
final Class<? extends Builder<? extends Props>> builder = getBuilderForClass(clazz); | ||
final Builder<? extends Props> value = _mapper.readValue(treeNode.toString(), builder); |
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 should be able to avoid the toString 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.
I think I found a suitable alternative. Docs indicate that it should be more efficient.
@Override | ||
public Props deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { | ||
final TreeNode treeNode = p.readValueAsTree(); | ||
final String type = ((TextNode) treeNode.get("type")).textValue(); |
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 seems like a bit of reinvention. Type mapping is already supported by Jackson, I know we haven't used it, but I think so far we've avoided this level of generality. For example we have a getClass helper from config which we then use to deserialize but we never fetch the builder by hand. Could we just do something like that 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.
I tried, but I couldn't pull it off. This was the best I was able to do. Everything else got.... interestingly broken. It had to do with the return type all being Props, but the deserializer not being a subclass of Props and the fact that each Props will have a different constructor. I don't think Jackson was setup to do that.
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.
Hrm. Ok.
The use case seems to me be a combination of 1) Polymorphism; different builder types as determined by a field; 2) The use of a builder. In the first we've either done explicit type request via a TypeReference or annotation based binding via a type field.
Props is final so you can't wrap it or extend it in order to annotate it.
http://doc.akka.io/japi/akka/2.4.0/akka/actor/Props.html
The problem seems to be that we're storing any Props here for the _clusterJoinerActor which is not type-complete (I'm guess not just any actor can be a "joiner actor").
For example, if the Props were wrapped with NonJoiningClusterJoiner and we used that type here (or more correctly an interface of that type) then we would be just to a manageable polymorphic deserialization problem (e.g. annotate the subclasses of that interface). Using Props directly corners us in many ways, and doesn't help describe what is actually required here.
Happy to discuss.
4bb2285
to
ac364ff
Compare
@@ -429,6 +455,8 @@ public Builder setDatabaseConfigurations(final Map<String, DatabaseConfiguration | |||
private RebalanceConfiguration _rebalanceConfiguration; | |||
@NotNull | |||
private String _clusterHostSuffix = ""; | |||
@NotNull | |||
private Props _clusterJoinActor = new NonJoiningClusterJoiner.Builder().build(); |
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 isn't actually an actor. Do we want it to be? In the past we've done that through Guice, but as this is configuration I am inclined to say it's Props, but the name should probably reflect that.
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.
At the end of the day it becomes an actor. I don't want the people configuring the service to have to know that they're actually building a Props that will get created into an actor. As far as they know, they want to configure an actor.
Also, the class that you give it in the config is an actor. It's just the actor builder that need to build a Props to create the actor.
b73765f
to
18a22d9
Compare
I've addressed most of the concerns. The implementation doesn't feel quite right still, but the semantics of the config file match what I want. It feels like there is still something to do for the declared type on the config classes, or perhaps in the way it polymorphically deserialize (or, rather, the way it doesn't use the built-in Jackson polymorphic deserialization). |
1837c08
to
3cc4086
Compare
e8a63f4
to
b420e27
Compare
b420e27
to
290c558
Compare
Just a preview. I need to add the GraphiteSink back in with Akka actors. I might also pull out the updates from the ActorBuilder stuff.