From: David ‘Bombe’ Roden Date: Mon, 17 Mar 2014 19:38:02 +0000 (+0100) Subject: Refactor engine, use Optionals in the state manager. X-Git-Tag: v2~260 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=1f272e712b8a1142dd6cf6db3cc43bb0bc63b9bc;p=rhynodge.git Refactor engine, use Optionals in the state manager. --- diff --git a/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java b/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java index 23fa69b..dcf3a39 100644 --- a/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java +++ b/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java @@ -17,6 +17,9 @@ package net.pterodactylus.rhynodge.engine; +import static com.google.common.base.Optional.absent; +import static com.google.common.base.Optional.of; + import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -25,16 +28,17 @@ import java.util.SortedMap; import net.pterodactylus.rhynodge.Filter; import net.pterodactylus.rhynodge.Query; import net.pterodactylus.rhynodge.Reaction; +import net.pterodactylus.rhynodge.State; import net.pterodactylus.rhynodge.Trigger; import net.pterodactylus.rhynodge.states.AbstractState; import net.pterodactylus.rhynodge.states.FailedState; import net.pterodactylus.rhynodge.states.StateManager; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.log4j.Logger; - +import com.google.common.base.Optional; import com.google.common.collect.Maps; import com.google.common.util.concurrent.AbstractExecutionThreadService; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.log4j.Logger; /** * Rhynodge main engine. @@ -108,45 +112,24 @@ public class Engine extends AbstractExecutionThreadService { @Override public void run() { while (isRunning()) { - - /* delay if we have no reactions. */ - synchronized (reactions) { - if (reactions.isEmpty()) { - logger.debug("Sleeping while no Reactions available."); - try { - reactions.wait(); - } catch (InterruptedException ie1) { - /* ignore, we’re looping anyway. */ - } - continue; - } + Optional nextReaction = getNextReaction(); + if (!nextReaction.isPresent()) { + continue; } - /* find next reaction. */ - SortedMap> nextReactions = Maps.newTreeMap(); - String reactionName; - Reaction nextReaction; - synchronized (reactions) { - for (Entry reactionEntry : reactions.entrySet()) { - net.pterodactylus.rhynodge.State state = stateManager.loadLastState(reactionEntry.getKey()); - long stateTime = (state != null) ? state.time() : 0; - nextReactions.put(stateTime + reactionEntry.getValue().updateInterval(), Pair.of(reactionEntry.getKey(), reactionEntry.getValue())); - } - reactionName = nextReactions.get(nextReactions.firstKey()).getLeft(); - nextReaction = nextReactions.get(nextReactions.firstKey()).getRight(); - } + String reactionName = nextReaction.get().name(); logger.debug(String.format("Next Reaction: %s.", reactionName)); /* wait until the next reaction has to run. */ - net.pterodactylus.rhynodge.State lastState = stateManager.loadLastState(reactionName); - long lastStateTime = (lastState != null) ? lastState.time() : 0; - int lastStateFailCount = (lastState != null) ? lastState.failCount() : 0; - long waitTime = (lastStateTime + nextReaction.updateInterval()) - System.currentTimeMillis(); + Optional lastState = stateManager.loadLastState(reactionName); + long lastStateTime = lastState.isPresent() ? lastState.get().time() : 0; + int lastStateFailCount = lastState.isPresent() ? lastState.get().failCount() : 0; + long waitTime = (lastStateTime + nextReaction.get().updateInterval()) - System.currentTimeMillis(); logger.debug(String.format("Time to wait for next Reaction: %d millseconds.", waitTime)); if (waitTime > 0) { synchronized (reactions) { try { - logger.info(String.format("Waiting until %tc.", lastStateTime + nextReaction.updateInterval())); + logger.info(String.format("Waiting until %tc.", lastStateTime + nextReaction.get().updateInterval())); reactions.wait(waitTime); } catch (InterruptedException ie1) { /* we’re looping! */ @@ -159,7 +142,7 @@ public class Engine extends AbstractExecutionThreadService { /* run reaction. */ logger.info(String.format("Running Query for %s...", reactionName)); - Query query = nextReaction.query(); + Query query = nextReaction.get().query(); net.pterodactylus.rhynodge.State state; try { logger.debug("Querying system..."); @@ -177,7 +160,7 @@ public class Engine extends AbstractExecutionThreadService { logger.debug(String.format("State is %s.", state)); /* convert states. */ - for (Filter filter : nextReaction.filters()) { + for (Filter filter : nextReaction.get().filters()) { if (state.success()) { net.pterodactylus.rhynodge.State newState = filter.filter(state); logger.debug(String.format("Old state is %s, new state is %s.", state, newState)); @@ -187,13 +170,13 @@ public class Engine extends AbstractExecutionThreadService { if (!state.success()) { state.setFailCount(lastStateFailCount + 1); } - net.pterodactylus.rhynodge.State lastSuccessfulState = stateManager.loadLastSuccessfulState(reactionName); + Optional lastSuccessfulState = stateManager.loadLastSuccessfulState(reactionName); /* merge states. */ boolean triggerHit = false; - Trigger trigger = nextReaction.trigger(); - if ((lastSuccessfulState != null) && lastSuccessfulState.success() && state.success()) { - net.pterodactylus.rhynodge.State newState = trigger.mergeStates(lastSuccessfulState, state); + Trigger trigger = nextReaction.get().trigger(); + if (lastSuccessfulState.isPresent() && lastSuccessfulState.get().success() && state.success()) { + net.pterodactylus.rhynodge.State newState = trigger.mergeStates(lastSuccessfulState.get(), state); /* save new state. */ stateManager.saveState(reactionName, newState); @@ -208,10 +191,38 @@ public class Engine extends AbstractExecutionThreadService { logger.debug(String.format("Trigger was hit: %s.", triggerHit)); if (triggerHit) { logger.info("Executing Action..."); - nextReaction.action().execute(trigger.output(nextReaction)); + nextReaction.get().action().execute(trigger.output(nextReaction.get())); + } + + } + } + + private Optional getNextReaction() { + while (isRunning()) { + synchronized (reactions) { + if (reactions.isEmpty()) { + logger.debug("Sleeping while no Reactions available."); + try { + reactions.wait(); + } catch (InterruptedException ie1) { + /* ignore, we’re looping anyway. */ + } + continue; + } } + /* find next reaction. */ + SortedMap> nextReactions = Maps.newTreeMap(); + synchronized (reactions) { + for (Entry reactionEntry : reactions.entrySet()) { + Optional state = stateManager.loadLastState(reactionEntry.getKey()); + long stateTime = state.isPresent() ? state.get().time() : 0; + nextReactions.put(stateTime + reactionEntry.getValue().updateInterval(), Pair.of(reactionEntry.getKey(), reactionEntry.getValue())); + } + return of(nextReactions.get(nextReactions.firstKey()).getRight()); + } } + return absent(); } } diff --git a/src/main/java/net/pterodactylus/rhynodge/states/StateManager.java b/src/main/java/net/pterodactylus/rhynodge/states/StateManager.java index 19eccba..35125bb 100644 --- a/src/main/java/net/pterodactylus/rhynodge/states/StateManager.java +++ b/src/main/java/net/pterodactylus/rhynodge/states/StateManager.java @@ -17,11 +17,15 @@ package net.pterodactylus.rhynodge.states; +import static com.google.common.base.Optional.absent; +import static com.google.common.base.Optional.fromNullable; + import java.io.File; import java.io.IOException; import net.pterodactylus.rhynodge.State; +import com.google.common.base.Optional; import org.apache.log4j.Logger; import com.fasterxml.jackson.core.JsonGenerationException; @@ -64,10 +68,10 @@ public class StateManager { * * @param reactionName * The name of the reaction - * @return The loaded state, or {@code null} if the state could not be + * @return The loaded state, or {@link Optional#absent()} if the state could not be * loaded */ - public State loadLastState(String reactionName) { + public Optional loadLastState(String reactionName) { return loadLastState(reactionName, false); } @@ -76,10 +80,10 @@ public class StateManager { * * @param reactionName * The name of the reaction - * @return The loaded state, or {@code null} if the state could not be + * @return The loaded state, or {@link Optional#absent()} if the state could not be * loaded */ - public State loadLastSuccessfulState(String reactionName) { + public Optional loadLastSuccessfulState(String reactionName) { return loadLastState(reactionName, true); } @@ -133,14 +137,14 @@ public class StateManager { * @param successful * {@code true} to load the last successful state, {@code false} * to load the last state - * @return The loaded state, or {@code null} if the state could not be + * @return The loaded state, or {@link Optional#absent()} if the state could not be * loaded */ - private State loadLastState(String reactionName, boolean successful) { + private Optional loadLastState(String reactionName, boolean successful) { File stateFile = stateFile(reactionName, successful ? "success" : "last"); try { State state = objectMapper.readValue(stateFile, AbstractState.class); - return state; + return fromNullable(state); } catch (JsonParseException jpe1) { logger.warn(String.format("State for Reaction “%s” could not be parsed.", reactionName), jpe1); } catch (JsonMappingException jme1) { @@ -148,7 +152,7 @@ public class StateManager { } catch (IOException ioe1) { logger.info(String.format("State for Reaction “%s” could not be found.", reactionName)); } - return null; + return absent(); } }