X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Frhynodge%2Fengine%2FEngine.java;h=2ff7666e5369ac35a9fb67212a6d6e3d2a3a7fae;hb=d7ad1bb8808e3937c505eed9d7b3b6a12bd9783b;hp=9e4d883706222a5fd7deeaf771a327e20c9b84b7;hpb=6f69aff66ba5617d0bb27874014b4274bc551ab8;p=rhynodge.git diff --git a/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java b/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java index 9e4d883..2ff7666 100644 --- a/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java +++ b/src/main/java/net/pterodactylus/rhynodge/engine/Engine.java @@ -17,6 +17,11 @@ package net.pterodactylus.rhynodge.engine; +import static com.google.common.base.Optional.absent; +import static com.google.common.base.Optional.of; +import static com.google.common.collect.Maps.newTreeMap; +import static java.lang.String.format; + import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -30,12 +35,11 @@ import net.pterodactylus.rhynodge.states.AbstractState; import net.pterodactylus.rhynodge.states.FailedState; import net.pterodactylus.rhynodge.states.StateManager; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.AbstractExecutionThreadService; import org.apache.commons.lang3.tuple.Pair; import org.apache.log4j.Logger; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.AbstractExecutionThreadService; - /** * Rhynodge main engine. * @@ -108,45 +112,23 @@ 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(); - } - logger.debug(String.format("Next Reaction: %s.", reactionName)); + String reactionName = nextReaction.get().getKey(); + logger.debug(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(); - logger.debug(String.format("Time to wait for next Reaction: %d millseconds.", waitTime)); + Optional lastState = stateManager.loadLastState(reactionName); + int lastStateFailCount = lastState.isPresent() ? lastState.get().failCount() : 0; + long waitTime = nextReaction.get().getNextTime() - System.currentTimeMillis(); + logger.debug(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(format("Waiting until %tc.", nextReaction.get().getNextTime())); reactions.wait(waitTime); } catch (InterruptedException ie1) { /* we’re looping! */ @@ -158,8 +140,8 @@ public class Engine extends AbstractExecutionThreadService { } /* run reaction. */ - logger.info(String.format("Running Query for %s...", reactionName)); - Query query = nextReaction.query(); + logger.info(format("Running Query for %s...", reactionName)); + Query query = nextReaction.get().getReaction().query(); net.pterodactylus.rhynodge.State state; try { logger.debug("Querying system..."); @@ -174,38 +156,99 @@ public class Engine extends AbstractExecutionThreadService { /* no further state. */ }; } - logger.debug(String.format("State is %s.", state)); + logger.debug(format("State is %s.", state)); /* convert states. */ - for (Filter filter : nextReaction.filters()) { + for (Filter filter : nextReaction.get().getReaction().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)); + //logger.debug(String.format("Old state is %s, new state is %s.", state, newState)); state = newState; } } if (!state.success()) { state.setFailCount(lastStateFailCount + 1); } - net.pterodactylus.rhynodge.State lastSuccessfulState = stateManager.loadLastSuccessfulState(reactionName); - stateManager.saveState(reactionName, state); + Optional lastSuccessfulState = stateManager.loadLastSuccessfulState(reactionName); - /* only run trigger if we have collected two successful states. */ - Trigger trigger = nextReaction.trigger(); + /* merge states. */ boolean triggerHit = false; - if ((lastSuccessfulState != null) && lastSuccessfulState.success() && state.success()) { - logger.debug("Checking Trigger for changes..."); - triggerHit = trigger.triggers(state, lastSuccessfulState); + Trigger trigger = nextReaction.get().getReaction().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); + + triggerHit = trigger.triggers(); + } else { + /* save first or error state. */ + stateManager.saveState(reactionName, state); } /* run action if trigger was hit. */ - logger.debug(String.format("Trigger was hit: %s.", triggerHit)); + logger.debug(format("Trigger was hit: %s.", triggerHit)); if (triggerHit) { logger.info("Executing Action..."); - nextReaction.action().execute(trigger.output(nextReaction)); + nextReaction.get().getReaction().action().execute(trigger.output(nextReaction.get().getReaction())); + } + + } + } + + 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 = 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())); + } + Pair keyReaction = nextReactions.get(nextReactions.firstKey()); + return of(new NextReaction(keyReaction.getKey(), keyReaction.getValue(), nextReactions.firstKey())); + } + } + return absent(); + } + + private static class NextReaction { + + private final String key; + private final Reaction reaction; + private final long nextTime; + + private NextReaction(String key, Reaction reaction, long nextTime) { + this.key = key; + this.reaction = reaction; + this.nextTime = nextTime; } + + public String getKey() { + return key; + } + + public Reaction getReaction() { + return reaction; + } + + public long getNextTime() { + return nextTime; + } + } }