Ignore chains and states default directories.
[rhynodge.git] / src / main / java / net / pterodactylus / reactor / engine / Engine.java
index 74b01b1..6f4376b 100644 (file)
@@ -47,12 +47,22 @@ public class Engine extends AbstractExecutionThreadService {
        private static final Logger logger = Logger.getLogger(Engine.class);
 
        /** The state manager. */
-       private final StateManager stateManager = new StateManager("states");
+       private final StateManager stateManager;
 
        /** All defined reactions. */
        /* synchronize on itself. */
        private final Map<String, Reaction> reactions = new HashMap<String, Reaction>();
 
+       /**
+        * Creates a new engine.
+        *
+        * @param stateManager
+        *            The state manager
+        */
+       public Engine(StateManager stateManager) {
+               this.stateManager = stateManager;
+       }
+
        //
        // ACCESSORS
        //
@@ -64,15 +74,9 @@ public class Engine extends AbstractExecutionThreadService {
         *            The name of the reaction
         * @param reaction
         *            The reaction to add to this engine
-        * @throws IllegalStateException
-        *             if the engine already contains a {@link Reaction} with the
-        *             given name
         */
        public void addReaction(String name, Reaction reaction) {
                synchronized (reactions) {
-                       if (reactions.containsKey(name)) {
-                               throw new IllegalStateException(String.format("Engine already contains a Reaction named “%s!”", name));
-                       }
                        reactions.put(name, reaction);
                        reactions.notifyAll();
                }
@@ -124,24 +128,25 @@ public class Engine extends AbstractExecutionThreadService {
                        Reaction nextReaction;
                        synchronized (reactions) {
                                for (Entry<String, Reaction> reactionEntry : reactions.entrySet()) {
-                                       net.pterodactylus.reactor.State state = stateManager.loadState(reactionEntry.getKey());
+                                       net.pterodactylus.reactor.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.", nextReaction));
+                       logger.debug(String.format("Next Reaction: %s.", reactionName));
 
                        /* wait until the next reaction has to run. */
-                       net.pterodactylus.reactor.State lastState = stateManager.loadState(reactionName);
+                       net.pterodactylus.reactor.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));
                        if (waitTime > 0) {
                                synchronized (reactions) {
                                        try {
-                                               logger.debug(String.format("Waiting for %d milliseconds.", waitTime));
+                                               logger.info(String.format("Waiting until %tc.", lastStateTime + nextReaction.updateInterval()));
                                                reactions.wait(waitTime);
                                        } catch (InterruptedException ie1) {
                                                /* we’re looping! */
@@ -153,6 +158,7 @@ public class Engine extends AbstractExecutionThreadService {
                        }
 
                        /* run reaction. */
+                       logger.info(String.format("Running Query for %s...", reactionName));
                        Query query = nextReaction.query();
                        net.pterodactylus.reactor.State state;
                        try {
@@ -178,23 +184,25 @@ public class Engine extends AbstractExecutionThreadService {
                                        state = newState;
                                }
                        }
-                       if (state.success()) {
-                               stateManager.saveState(reactionName, state);
+                       if (!state.success()) {
+                               state.setFailCount(lastStateFailCount + 1);
                        }
+                       net.pterodactylus.reactor.State lastSuccessfulState = stateManager.loadLastSuccessfulState(reactionName);
+                       stateManager.saveState(reactionName, state);
 
-                       /* only run trigger if we have collected two states. */
+                       /* only run trigger if we have collected two successful states. */
                        Trigger trigger = nextReaction.trigger();
                        boolean triggerHit = false;
-                       if ((lastState != null) && state.success()) {
+                       if ((lastSuccessfulState != null) && lastSuccessfulState.success() && state.success()) {
                                logger.debug("Checking Trigger for changes...");
-                               triggerHit = trigger.triggers(state, lastState);
+                               triggerHit = trigger.triggers(state, lastSuccessfulState);
                        }
 
                        /* run action if trigger was hit. */
                        logger.debug(String.format("Trigger was hit: %s.", triggerHit));
                        if (triggerHit) {
                                logger.info("Executing Action...");
-                               nextReaction.action().execute(trigger.output());
+                               nextReaction.action().execute(trigger.output(nextReaction));
                        }
 
                }