bug[ats_H5NS7]: Rate limit branch cache refresh requests

Change-Id: I747c69a7c0d1810a6679ea2ecb17bd6f4f0a731e
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/BranchManager.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/BranchManager.java
index 5ed5625..a806b52 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/BranchManager.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/BranchManager.java
@@ -44,6 +44,7 @@
 import org.eclipse.osee.framework.core.operation.OperationBuilder;
 import org.eclipse.osee.framework.core.operation.Operations;
 import org.eclipse.osee.framework.core.util.Conditions;
+import org.eclipse.osee.framework.database.core.OseeInfo;
 import org.eclipse.osee.framework.database.core.SQL3DataType;
 import org.eclipse.osee.framework.jdk.core.util.GUID;
 import org.eclipse.osee.framework.jdk.core.util.Strings;
@@ -119,7 +120,18 @@
    }
 
    public static void refreshBranches() throws OseeCoreException {
-      getCache().reloadCache();
+      String refreshWindow = OseeInfo.getCachedValue("cache.reload.throttle.millis");
+      boolean reload = true;
+      if (Strings.isNumeric(refreshWindow)) {
+         long timeInMillis = Long.parseLong(refreshWindow);
+         long diff = System.currentTimeMillis() - getCache().getLastLoaded();
+         if (diff < timeInMillis) {
+            reload = false;
+         }
+      }
+      if (reload) {
+         getCache().reloadCache();
+      }
    }
 
    public static Branch getBranch(DefaultBasicGuidArtifact guidArt) throws OseeCoreException {
@@ -153,14 +165,24 @@
       }
    }
 
-   public static Branch getBranchByGuid(String guid) throws OseeCoreException {
-      BranchCache cache = getCache();
-      Branch branch = cache.getByGuid(guid);
-      if (branch == null) {
-         if (cache.reloadCache()) {
-            branch = cache.getByGuid(guid);
-         }
+   /**
+    * Do not call this method unless absolutely neccessary due to performance impacts.
+    */
+   public static synchronized void checkAndReload(String guid) throws OseeCoreException {
+      if (!branchExists(guid)) {
+         refreshBranches();
       }
+   }
+
+   public static synchronized void checkAndReload(int id) throws OseeCoreException {
+      if (!branchExists(id)) {
+         refreshBranches();
+      }
+   }
+
+   public static Branch getBranchByGuid(String guid) throws OseeCoreException {
+      //      checkAndReload(guid);
+      Branch branch = getCache().getByGuid(guid);
       if (branch == null) {
          throw new BranchDoesNotExist("Branch with guid [%s] does not exist", guid);
       }
@@ -175,6 +197,10 @@
       return getCache().getByGuid(branchGuid) != null;
    }
 
+   public static boolean branchExists(int id) throws OseeCoreException {
+      return getCache().getById(id) != null;
+   }
+
    /**
     * returns the merge branch for this source destination pair from the cache or null if not found
     */
@@ -222,15 +248,8 @@
          throw new BranchDoesNotExist("Branch Id is null");
       }
 
-      BranchCache cache = getCache();
-      // If someone else made a branch on another machine, we may not know about it
-      // so refresh the cache.
-      Branch branch = cache.getById(branchId);
-      if (branch == null) {
-         if (cache.reloadCache()) {
-            branch = cache.getById(branchId);
-         }
-      }
+      checkAndReload(branchId);
+      Branch branch = getCache().getById(branchId);
       if (branch == null) {
          throw new BranchDoesNotExist("Branch could not be acquired for branch id %d", branchId);
       }
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/event/model/BranchEventType.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/event/model/BranchEventType.java
index 7b74345..743d48d 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/event/model/BranchEventType.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/event/model/BranchEventType.java
@@ -17,14 +17,14 @@
 
    // Local and Remote events
    Purging(EventType.LocalAndRemote, "ATPHeMoAFyL543vrAyQA", false),
-   Purged(EventType.LocalAndRemote, "AAn_QG7jRGZAqPE0UewA", true),
+   Purged(EventType.LocalAndRemote, "AAn_QG7jRGZAqPE0UewA", false),
    Deleting(EventType.LocalAndRemote, "ATPHeNujxAkPZEkWUtQA", false),
-   Deleted(EventType.LocalAndRemote, "AAn_QHBDvwtT5jjKaHgA", true),
+   Deleted(EventType.LocalAndRemote, "AAn_QHBDvwtT5jjKaHgA", false),
    Added(EventType.LocalAndRemote, "AAn_QHDohywDoSTxwcQA", true),
    Renamed(EventType.LocalAndRemote, "AAn_QHGLIUsH2BdX2gwA", true),
    Committing(EventType.LocalAndRemote, "ATPHeN1du2GAbS3SQsAA", false),
    CommitFailed(EventType.LocalAndRemote, "ATPHeN3RaBnDmpoYXkQA", false),
-   Committed(EventType.LocalAndRemote, "AAn_QHIu0mGZytQ11QwA", true),
+   Committed(EventType.LocalAndRemote, "AAn_QHIu0mGZytQ11QwA", false),
    TypeUpdated(EventType.LocalAndRemote, "AAn_QHLW4DKKbUkEZggA", true),
    StateUpdated(EventType.LocalAndRemote, "AAn_QHQdKhxNLtWPchAA", true),
    ArchiveStateUpdated(EventType.LocalAndRemote, "AAn_QHS7Zhr6OLhKl3gA", true),
@@ -66,4 +66,13 @@
       return justifiesCacheRefresh;
    }
 
+   public boolean matches(BranchEventType... branchEventTypes) {
+      for (BranchEventType branchEventType : branchEventTypes) {
+         if (this == branchEventType) {
+            return true;
+         }
+      }
+      return false;
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/ArtifactRemoteEventHandler.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/ArtifactRemoteEventHandler.java
index a2cd09f..33a3d92 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/ArtifactRemoteEventHandler.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/ArtifactRemoteEventHandler.java
@@ -57,31 +57,34 @@
       transport.send(sender, transEvent);
    }
 
-   private void updateArtifacts(Sender sender, Collection<EventBasicGuidArtifact> artifacts, int transactionId) {
+   private void updateArtifacts(Sender sender, Collection<EventBasicGuidArtifact> artifacts, int transactionId) throws OseeCoreException {
       // Don't crash on any one artifact update problem (no update method throughs exceptions)
       for (EventBasicGuidArtifact guidArt : artifacts) {
          EventUtil.eventLog(String.format("REM: updateArtifact -> [%s]", guidArt));
          EventModType eventModType = guidArt.getModType();
-         switch (eventModType) {
-            case Added:
-               // Handle Added Artifacts
-               // Nothing to do for added cause they're not in cache yet.  Apps will load if they need them.
-               // do nothing cause not in cache
-               break;
-            case Modified:
-               updateModifiedArtifact((EventModifiedBasicGuidArtifact) guidArt, transactionId);
-               break;
-            case ChangeType:
-               ChangeArtifactType.handleRemoteChangeType((EventChangeTypeBasicGuidArtifact) guidArt);
-               break;
-            case Deleted:
-            case Purged:
-               updateDeletedArtifact(guidArt);
-               break;
-            default:
-               // Unknown mod type
-               EventUtil.eventLog(String.format("REM: updateArtifacts - Unhandled mod type [%s]", guidArt.getModType()));
-               break;
+         if (BranchManager.branchExists(guidArt.getBranchGuid())) {
+            switch (eventModType) {
+               case Added:
+                  // Handle Added Artifacts
+                  // Nothing to do for added cause they're not in cache yet.  Apps will load if they need them.
+                  // do nothing cause not in cache
+                  break;
+               case Modified:
+                  updateModifiedArtifact((EventModifiedBasicGuidArtifact) guidArt, transactionId);
+                  break;
+               case ChangeType:
+                  ChangeArtifactType.handleRemoteChangeType((EventChangeTypeBasicGuidArtifact) guidArt);
+                  break;
+               case Deleted:
+               case Purged:
+                  updateDeletedArtifact(guidArt);
+                  break;
+               default:
+                  // Unknown mod type
+                  EventUtil.eventLog(String.format("REM: updateArtifacts - Unhandled mod type [%s]",
+                     guidArt.getModType()));
+                  break;
+            }
          }
       }
    }
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchEventHandler.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchEventHandler.java
index 8835fad9..e3f49fc 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchEventHandler.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchEventHandler.java
@@ -12,6 +12,8 @@
 
 import java.util.List;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+import org.eclipse.osee.framework.skynet.core.event.EventUtil;
 import org.eclipse.osee.framework.skynet.core.event.FrameworkEventUtil;
 import org.eclipse.osee.framework.skynet.core.event.filter.IEventFilter;
 import org.eclipse.osee.framework.skynet.core.event.listener.IBranchEventListener;
@@ -37,6 +39,13 @@
             }
          }
       }
+      if (event.getEventType() == BranchEventType.Added) {
+         try {
+            BranchManager.checkAndReload(event.getBranchGuid());
+         } catch (OseeCoreException ex) {
+            EventUtil.eventLog("IEM: updateBranches", ex);
+         }
+      }
       // Call listener if we matched all of the filters
       listener.handleBranchEvent(sender, event);
    }
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchRemoteEventHandler.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchRemoteEventHandler.java
index a0454c1..93e38d3 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchRemoteEventHandler.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/internal/event/handlers/BranchRemoteEventHandler.java
@@ -42,33 +42,36 @@
 
    private void updateBranches(Sender sender, BranchEvent branchEvent) {
       BranchEventType eventType = branchEvent.getEventType();
+      String branchGuid = branchEvent.getBranchGuid();
       try {
-         if (eventType == Committed) {
-            Branch branch = BranchManager.getBranchByGuid(branchEvent.getBranchGuid());
-            Artifact artifact = BranchManager.getAssociatedArtifact(branch);
-            TransactionManager.clearCommitArtifactCacheForAssociatedArtifact(artifact);
-         } else if (eventType == Purged) {
-            handleBranchRemoval(BranchState.PURGED, branchEvent.getBranchGuid());
-         } else if (eventType == Deleted) {
-            handleBranchRemoval(BranchState.DELETED, branchEvent.getBranchGuid());
+         if (BranchManager.branchExists(branchGuid)) {
+            Branch branch = BranchManager.getBranchByGuid(branchGuid);
+            if (eventType == Committed) {
+               Artifact artifact = BranchManager.getAssociatedArtifact(branch);
+               TransactionManager.clearCommitArtifactCacheForAssociatedArtifact(artifact);
+               updateBranchState(BranchState.COMMITTED, branch);
+            } else if (eventType == Purged) {
+               updateBranchState(BranchState.PURGED, branch);
+            } else if (eventType == Deleted) {
+               updateBranchState(BranchState.DELETED, branch);
+            }
          }
 
          if (eventType.justifiesCacheRefresh()) {
-            BranchManager.invalidateBranches();
+            BranchManager.refreshBranches();
          }
       } catch (Exception ex) {
          EventUtil.eventLog("REM: updateBranches", ex);
       }
    }
 
-   private void handleBranchRemoval(BranchState state, String guid) throws OseeCoreException {
-      if (BranchManager.branchExists(guid)) {
-         Branch branch = BranchManager.getBranchByGuid(guid);
-         branch.setBranchState(state);
+   private void updateBranchState(BranchState state, Branch branch) throws OseeCoreException {
+      if (state.matches(BranchState.PURGED, BranchState.DELETED)) {
          branch.setArchived(true);
-         branch.clearDirty();
          BranchManager.decache(branch);
       }
+      branch.setBranchState(state);
+      branch.clearDirty();
    }
 
 }