azkaban-developers

added developers cache

7/2/2019 3:27:31 AM

Details

diff --git a/azkaban-common/build.gradle b/azkaban-common/build.gradle
index d747d52..658344f 100644
--- a/azkaban-common/build.gradle
+++ b/azkaban-common/build.gradle
@@ -14,13 +14,7 @@
  * the License.
  */
 
-plugins {
-    id "io.freefair.aspectj.post-compile-weaving" version "3.1.4"
-}
-
 dependencies {
-    aspect 'br.ufrgs.inf.prosoft.applicationtracer:ApplicationTracer:1.0'
-
     compile project(':az-core')
     compile project(':azkaban-spi')
     compile project(':azkaban-db')
diff --git a/azkaban-common/src/main/java/azkaban/executor/ActiveExecutors.java b/azkaban-common/src/main/java/azkaban/executor/ActiveExecutors.java
index 67235f8..36691d4 100644
--- a/azkaban-common/src/main/java/azkaban/executor/ActiveExecutors.java
+++ b/azkaban-common/src/main/java/azkaban/executor/ActiveExecutors.java
@@ -22,6 +22,9 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.apache.log4j.Logger;
 
+import br.ufrgs.inf.prosoft.cache.GetterCache;
+
+
 /**
  * Loads & provides executors.
  */
@@ -30,7 +33,7 @@ public class ActiveExecutors {
 
   private static final Logger logger = Logger.getLogger(ExecutorManager.class);
 
-  private volatile ImmutableSet<Executor> activeExecutors;
+  // private volatile ImmutableSet<Executor> activeExecutors;
   private final ExecutorLoader executorLoader;
 
   @Inject
@@ -45,7 +48,6 @@ public class ActiveExecutors {
    * fails.
    */
   public void setupExecutors() throws ExecutorManagerException {
-    // meloca cache
     // final ImmutableSet<Executor> newExecutors = loadExecutors();
     // if (newExecutors.isEmpty()) {
     //   final String error = "No active executors found";
@@ -56,26 +58,30 @@ public class ActiveExecutors {
     // }
   }
 
+  public static GetterCache<Collection<Executor>> getAllCache = new GetterCache<>("ActiveExecutors.getAll");
+
   /**
    * Returns all executors. The result is cached. To reload, call {@link #setupExecutors()}.
    *
    * @return all executors
    */
   public Collection<Executor> getAll() {
-    // meloca cache
-    try{
-      final ImmutableSet<Executor> newExecutors = loadExecutors();
-      if (newExecutors.isEmpty()) {
-        final String error = "No active executors found";
-        logger.error(error);
-      } else {
-        this.activeExecutors = newExecutors;
+    return getAllCache.computeIfAbsent(() -> {
+      ImmutableSet<Executor> activeExecutors = ImmutableSet.of();
+      try{
+        final ImmutableSet<Executor> newExecutors = loadExecutors();
+        if (newExecutors.isEmpty()) {
+          final String error = "No active executors found";
+          logger.error(error);
+        } else {
+          activeExecutors = newExecutors;
+        }
+      } catch (ExecutorManagerException ex) {
+          logger.error("ExecutorManagerException: " + ex.getMessage());
+          activeExecutors = ImmutableSet.of();
       }
-    } catch (ExecutorManagerException ex) {
-        logger.error("ExecutorManagerException: " + ex.getMessage());
-        this.activeExecutors = ImmutableSet.of();
-    }
-    return this.activeExecutors;
+      return activeExecutors;
+    });
   }
 
   private ImmutableSet<Executor> loadExecutors() throws ExecutorManagerException {
diff --git a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
index b5a838a..07eb85d 100644
--- a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
+++ b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
@@ -47,6 +47,8 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.apache.log4j.Logger;
 
+import br.ufrgs.inf.prosoft.cache.MultiCache;
+import br.ufrgs.inf.prosoft.cache.KeyNotFoundException;
 
 @Singleton
 public class ProjectManager {
@@ -62,6 +64,8 @@ public class ProjectManager {
       // new ConcurrentHashMap<>();
   // private final CaseInsensitiveConcurrentHashMap<Project> projectsByName =
       // new CaseInsensitiveConcurrentHashMap<>();
+  public static MultiCache<String, Project> projectsByNameCache = new MultiCache<>("ProjectManager.projectsByName");
+  public static MultiCache<Integer, Project> projectsByIdCache = new MultiCache<>("ProjectManager.projectsById");
 
 
   @Inject
@@ -126,6 +130,10 @@ public class ProjectManager {
     //   this.projectsByName.put(proj.getName(), proj);
     //   this.projectsById.put(proj.getId(), proj);
     // }
+    for (final Project proj : projects) {
+      this.projectsByNameCache.put(proj.getName(), proj);
+      this.projectsByIdCache.put(proj.getId(), proj);
+    }
 
     for (final Project proj : projects) {
       loadAllProjectFlows(proj);
@@ -152,7 +160,7 @@ public class ProjectManager {
 
   public List<Project> getUserProjects(final User user) {
     final ArrayList<Project> array = new ArrayList<>();
-    for (final Project project : getProjects()) {
+    for (final Project project : this.projectsByIdCache.values()) {
     // for (final Project project : this.projectsById.values()) {
       final Permission perm = project.getUserPermission(user);
 
@@ -168,7 +176,7 @@ public class ProjectManager {
   public List<Project> getGroupProjects(final User user) {
     final List<Project> array = new ArrayList<>();
     // for (final Project project : this.projectsById.values()) {
-    for (final Project project : getProjects()) {
+    for (final Project project : this.projectsByIdCache.values()) {
       if (project.hasGroupPermission(user, Type.READ)) {
         array.add(project);
       }
@@ -186,7 +194,7 @@ public class ProjectManager {
       return array;
     }
 
-    for (final Project project : getProjects()) {
+    for (final Project project : this.projectsByIdCache.values()) {
     // for (final Project project : this.projectsById.values()) {
       final Permission perm = project.getUserPermission(user);
 
@@ -200,14 +208,10 @@ public class ProjectManager {
     }
     return array;
   }
-
+  
   public List<Project> getProjects() {
     // return new ArrayList<>(this.projectsById.values());
-    try {
-      return this.projectLoader.fetchAllActiveProjects();
-    } catch (final ProjectManagerException e) {
-      return new ArrayList<>();
-    }
+    return this.projectsByIdCache.values();
   }
 
   public List<Project> getProjectsByRegex(final String regexPattern) {
@@ -232,12 +236,7 @@ public class ProjectManager {
    */
   public Boolean isActiveProject(final int id) {
     // return this.projectsById.containsKey(id);
-    try {
-        this.projectLoader.fetchProjectById(id);
-        return true;
-      } catch (final ProjectManagerException e) {
-        return false;
-      }
+    return this.projectsByIdCache.containsKey(id);
   }
 
   /**
@@ -246,7 +245,11 @@ public class ProjectManager {
   public Project getProject(final String name) {
     // Project fetchedProject = this.projectsByName.get(name);
     Project fetchedProject = null;
-    if (fetchedProject == null) {
+    try {
+      fetchedProject = this.projectsByNameCache.get(name);
+    } catch (KeyNotFoundException ex) {
+    // }
+    // if (fetchedProject == null) {
       try {
         logger.info("Project " + name + " doesn't exist in cache, fetching from DB now.");
         fetchedProject = this.projectLoader.fetchProjectByName(name);
@@ -263,7 +266,10 @@ public class ProjectManager {
   public Project getProject(final int id) {
     // Project fetchedProject = this.projectsById.get(id);
     Project fetchedProject = null;
-    if (fetchedProject == null) {
+    try {
+      fetchedProject = this.projectsByIdCache.get(id);
+    } catch (KeyNotFoundException ex) {
+    // if (fetchedProject == null) {
       try {
         fetchedProject = this.projectLoader.fetchProjectById(id);
       } catch (final ProjectManagerException e) {
@@ -289,14 +295,17 @@ public class ProjectManager {
     final Project newProject;
     synchronized (this) {
       // if (this.projectsByName.containsKey(projectName)) {
-      //   throw new ProjectManagerException("Project already exists.");
-      // }
+      if (this.projectsByNameCache.containsKey(projectName)) {
+        throw new ProjectManagerException("Project already exists.");
+      }
 
       logger.info("Trying to create " + projectName + " by user "
           + creator.getUserId());
       newProject = this.projectLoader.createNewProject(projectName, description, creator);
       // this.projectsByName.put(newProject.getName(), newProject);
       // this.projectsById.put(newProject.getId(), newProject);
+      this.projectsByNameCache.put(newProject.getName(), newProject);
+      this.projectsByIdCache.put(newProject.getId(), newProject);
     }
 
     if (this.creatorDefaultPermissions) {
@@ -342,6 +351,8 @@ public class ProjectManager {
 
     // this.projectsByName.remove(project.getName());
     // this.projectsById.remove(project.getId());
+    this.projectsByNameCache.invalidate(project.getName());
+    this.projectsByIdCache.invalidate(project.getId());
 
     return project;
   }
diff --git a/azkaban-exec-server/build.gradle b/azkaban-exec-server/build.gradle
index ac5d5e6..8c01c99 100644
--- a/azkaban-exec-server/build.gradle
+++ b/azkaban-exec-server/build.gradle
@@ -14,15 +14,9 @@
  * the License.
  */
 
-plugins {
-    id "io.freefair.aspectj.post-compile-weaving" version "3.1.4"
-}
-
 apply plugin: 'distribution'
 
 dependencies {
-    aspect 'br.ufrgs.inf.prosoft.applicationtracer:ApplicationTracer:1.0'
-
     compile(project(':az-core'))
     compile(project(':azkaban-common'))
 
diff --git a/azkaban-exec-server/src/main/java/azkaban/execapp/ServerStatisticsServlet.java b/azkaban-exec-server/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
index e43bbff..5d08145 100644
--- a/azkaban-exec-server/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
+++ b/azkaban-exec-server/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.log4j.Logger;
 
+import br.ufrgs.inf.prosoft.cache.GetterCache;
 
 public class ServerStatisticsServlet extends HttpServlet {
 
@@ -69,7 +70,7 @@ public class ServerStatisticsServlet extends HttpServlet {
     //   this.populateStatistics(noCache);
     // }
 
-    this.populateStatistics(true);
+    this.populateStatistics(false);
 
     JSONUtils.toJSON(cachedstats, resp.getOutputStream(), true);
   }
@@ -191,22 +192,26 @@ public class ServerStatisticsServlet extends HttpServlet {
     return returnResult;
   }
 
+    public static GetterCache<ExecutorInfo> populateStatisticsCache = new GetterCache<>("ServerStatisticsServlet.populateStatistics");
+
   /**
    * call the data providers to fill the returning data container for statistics data. This function
    * refreshes the static cached copy of data in case if necessary.
    */
   protected synchronized void populateStatistics(final boolean noCache) {
-    //check again before starting the work.
-    if (noCache || System.currentTimeMillis() - lastRefreshedTime > cacheTimeInMilliseconds) {
-      final ExecutorInfo stats = new ExecutorInfo();
-
-      fillRemainingMemoryPercent(stats);
-      fillRemainingFlowCapacityAndLastDispatchedTime(stats);
-      fillCpuUsage(stats);
+    this.cachedstats = populateStatisticsCache.computeIfAbsent(() -> {
+      //check again before starting the work.
+      // if (noCache || System.currentTimeMillis() - lastRefreshedTime > cacheTimeInMilliseconds) {
+        final ExecutorInfo stats = new ExecutorInfo();
 
-      cachedstats = stats;
-      lastRefreshedTime = System.currentTimeMillis();
-    }
+        fillRemainingMemoryPercent(stats);
+        fillRemainingFlowCapacityAndLastDispatchedTime(stats);
+        fillCpuUsage(stats);
+        return stats;
+        // cachedstats = stats;
+        // lastRefreshedTime = System.currentTimeMillis();
+      // }
+    }, 1000);
   }
 
   /**

build.gradle 1(+1 -0)

diff --git a/build.gradle b/build.gradle
index b63e397..8650fc0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -165,6 +165,7 @@ subprojects {
         }
 
         dependencies {
+            compile "br.ufrgs.inf.prosoft.cache:Cache:1.0"
             compile deps.log4j
             compile deps.guice
             compile deps.slf4j

docker-compose.yml 10(+2 -8)

diff --git a/docker-compose.yml b/docker-compose.yml
index b213601..e89aaba 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,14 +5,8 @@ services:
     container_name: azkaban
     environment:
       - JAVA_OPTS=${JAVA_OPTS:-"-Xmx6124m"}
-      - TRACER_ENABLE=${TRACER_ENABLE:-true}
-      - TRACER_MINIMUM_EXECUTION_TIME=${TRACER_MINIMUM_EXECUTION_TIME:-1}
-      - TRACER_SERIALISE_INTERNALS=false
-      - TRACER_VERBOSE=true
-      - TRACER_TRACES=/caching-approaches-comparison/applications/traces/azkaban
-      - TRACER_IGNORED_PACKAGES=/caching-approaches-comparison/applications/uncached/azkaban/ignored
-      - TRACER_WHITELIST=/caching-approaches-comparison/applications/uncached/azkaban/whitelist
-      - TRACER_LOG=/caching-approaches-comparison/applications/output/azkaban-tracer.log
+      - CACHE_EVENTS=${CACHE_EVENTS:-/caching-approaches-comparison/applications/output/azkaban-developers-cache}
+      - CACHE_REGISTER_SIZE=false
     volumes:
       - application:/application
       - /root/.gradle:/home/gradle/.gradle