-
Notifications
You must be signed in to change notification settings - Fork 79
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
Refactor OriginsInventory. #62
Refactor OriginsInventory. #62
Conversation
mikkokar
commented
Jan 11, 2018
- Use QueueDrainingEventProcessor to ensure lockless consistency in face of concurrent updates.
- Improve origin state management for added/modified/removed monitored origins.
- Use event queue to ensure concurrent updates are handled correctly. - Improve ability to detect added/modified/removed origins.
enum Outcome { | ||
RELOADED, | ||
UNCHANGED | ||
} | ||
|
||
/** | ||
* Result or registry reload. |
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.
Result of registry reload?
@@ -17,6 +17,8 @@ | |||
|
|||
/** | |||
* Informed about state changes. | |||
* | |||
* @param <S> State type. |
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.
import static org.slf4j.LoggerFactory.getLogger; | ||
|
||
/** | ||
* An inventory of the origins configured for a single application. | ||
*/ | ||
@ThreadSafe | ||
public final class OriginsInventory | ||
implements OriginHealthStatusMonitor.Listener, OriginsCommandsListener, ActiveOrigins, OriginsInventoryStateChangeListener.Announcer, Closeable { | ||
implements OriginHealthStatusMonitor.Listener, |
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 number of interfaces here may indicate that this class is taking on too many responsibilities, but we can look into that later.
private final AtomicBoolean closed = new AtomicBoolean(false); | ||
|
||
private Map<Id, MonitoredOrigin> origins = ImmutableMap.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.
Why not just use Collections.emptyMap
as that does not require an external dependency.
@Override | ||
public void submit(Object event) { | ||
if (event instanceof SetOriginsEvent) { | ||
addOriginsEventHandler((SetOriginsEvent) event); |
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.
add or set?
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.
Renamed to setOriginsEventHandler
.
} | ||
|
||
public void addOriginsEventHandler(SetOriginsEvent event) { | ||
Set<Origin> newOrigins = event.newOrigins; |
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.
Suggested refactoring to encapsulate concept of origin changes:
Map<Id, Origin> newOriginsMap = event.newOrigins.stream()
.collect(toMap(Origin::id, o -> o));
OriginChanges originChanges = new OriginChanges();
concat(this.origins.keySet().stream(), newOriginsMap.keySet().stream()).collect(toSet()).forEach(
originId -> {
Origin origin = newOriginsMap.get(originId);
if (isNewOrigin(originId, origin)) {
MonitoredOrigin monitoredOrigin = addMonitoredEndpoint(origin);
originChanges.addOrReplaceOrigin(originId, monitoredOrigin);
} else if (isUpdatedOrigin(originId, origin)) {
MonitoredOrigin monitoredOrigin = changeMonitoredEndpoint(origin);
originChanges.addOrReplaceOrigin(originId, monitoredOrigin);
} else if (isUnchangedOrigin(originId, origin)) {
LOG.info("Existing origin has been left unchanged. Origin={}:{}", appId, origin);
originChanges.keepExistingOrigin(originId, this.origins.get(originId));
} else if (isRemovedOrigin(originId, origin)) {
removeMonitoredEndpoint(originId);
originChanges.noteRemovedOrigin();
}
}
);
this.origins = originChanges.updatedOrigins();
if (originChanges.changed()) {
notifyStateChange();
}
}
private class OriginChanges {
ImmutableMap.Builder<Id, MonitoredOrigin> monitoredOrigins = ImmutableMap.builder();
AtomicBoolean changed = new AtomicBoolean(false);
void addOrReplaceOrigin(Id originId, MonitoredOrigin origin) {
monitoredOrigins.put(originId, origin);
changed.set(true);
}
void keepExistingOrigin(Id originId, MonitoredOrigin origin) {
monitoredOrigins.put(originId, origin);
}
void noteRemovedOrigin() {
changed.set(true);
}
boolean changed() {
return changed.get();
}
Map<Id, MonitoredOrigin> updatedOrigins() {
return monitoredOrigins.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.
ok
@Test | ||
public void addingANewOriginWillAddToActiveSetAndInitiateTheMonitoring() { | ||
inventory.addOrigins(ORIGIN); | ||
public void setNewOrigins() { |
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 is this test trying to prove? Its name doesn't explain.
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
} | ||
|
||
@Test | ||
public void updatesOriginPortNumber() throws Exception { |
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 name is also not as informative as it could be. Perhaps something like "replaces origin when port number has changed"?
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.
Which is a longwinded way of saying "(origins inventory) updates origin port number" ;-)
} | ||
|
||
@Test | ||
public void updatesOriginHostName() throws Exception { |
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 name is also not as informative as it could be. Perhaps something like "replaces origin when host name has changed"?
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.
... again which is just a longer way saying "(origins inventory) updates origin host name".
} | ||
|
||
@Test | ||
public void stopsMonitoringModifiedOrigins() { |
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.
Stops and restarts?
* Refactor OriginsInventory. - Use event queue to ensure concurrent updates are handled correctly. - Improve ability to detect added/modified/removed origins.
Refactor OriginsInventory. (#62)