Merge "Merge branch 'stable-3.2' into stable-3.3" into stable-3.3
diff --git a/java/com/google/gerrit/server/AnonymousUser.java b/java/com/google/gerrit/server/AnonymousUser.java
index c96d61a..91d2d05 100644
--- a/java/com/google/gerrit/server/AnonymousUser.java
+++ b/java/com/google/gerrit/server/AnonymousUser.java
@@ -27,6 +27,12 @@
   }
 
   @Override
+  public Object getCacheKey() {
+    // Treat all anonymous users as a single user
+    return "anonymous";
+  }
+
+  @Override
   public String toString() {
     return "ANONYMOUS";
   }
diff --git a/java/com/google/gerrit/server/CurrentUser.java b/java/com/google/gerrit/server/CurrentUser.java
index 1955340..75afc04 100644
--- a/java/com/google/gerrit/server/CurrentUser.java
+++ b/java/com/google/gerrit/server/CurrentUser.java
@@ -90,6 +90,12 @@
    */
   public abstract GroupMembership getEffectiveGroups();
 
+  /**
+   * Returns a unique identifier for this user that is intended to be used as a cache key. Returned
+   * object should to implement {@code equals()} and {@code hashCode()} for effective caching.
+   */
+  public abstract Object getCacheKey();
+
   /** Unique name of the user on this server, if one has been assigned. */
   public Optional<String> getUserName() {
     return Optional.empty();
diff --git a/java/com/google/gerrit/server/IdentifiedUser.java b/java/com/google/gerrit/server/IdentifiedUser.java
index 14d74d0..7cafdc0 100644
--- a/java/com/google/gerrit/server/IdentifiedUser.java
+++ b/java/com/google/gerrit/server/IdentifiedUser.java
@@ -390,6 +390,11 @@
     return effectiveGroups;
   }
 
+  @Override
+  public Object getCacheKey() {
+    return getAccountId();
+  }
+
   public PersonIdent newRefLogIdent() {
     return newRefLogIdent(new Date(), TimeZone.getDefault());
   }
diff --git a/java/com/google/gerrit/server/InternalUser.java b/java/com/google/gerrit/server/InternalUser.java
index 821a0c6..381819d 100644
--- a/java/com/google/gerrit/server/InternalUser.java
+++ b/java/com/google/gerrit/server/InternalUser.java
@@ -36,6 +36,11 @@
   }
 
   @Override
+  public String getCacheKey() {
+    return "internal";
+  }
+
+  @Override
   public boolean isInternalUser() {
     return true;
   }
diff --git a/java/com/google/gerrit/server/PeerDaemonUser.java b/java/com/google/gerrit/server/PeerDaemonUser.java
index 8a8b67a..b27e05c 100644
--- a/java/com/google/gerrit/server/PeerDaemonUser.java
+++ b/java/com/google/gerrit/server/PeerDaemonUser.java
@@ -40,6 +40,11 @@
     return GroupMembership.EMPTY;
   }
 
+  @Override
+  public Object getCacheKey() {
+    return getRemoteAddress();
+  }
+
   public SocketAddress getRemoteAddress() {
     return peer;
   }
diff --git a/java/com/google/gerrit/server/query/change/SingleGroupUser.java b/java/com/google/gerrit/server/query/change/SingleGroupUser.java
index 7947b6b..c451d46 100644
--- a/java/com/google/gerrit/server/query/change/SingleGroupUser.java
+++ b/java/com/google/gerrit/server/query/change/SingleGroupUser.java
@@ -36,4 +36,9 @@
   public GroupMembership getEffectiveGroups() {
     return groups;
   }
+
+  @Override
+  public Object getCacheKey() {
+    return groups.getKnownGroups();
+  }
 }
diff --git a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
index 1cdca1b..de23ef4 100644
--- a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
+++ b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
@@ -101,6 +101,11 @@
         }
 
         @Override
+        public Object getCacheKey() {
+          return new Object();
+        }
+
+        @Override
         public boolean isIdentifiedUser() {
           return true;
         }
diff --git a/javatests/com/google/gerrit/server/permissions/RefControlTest.java b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
index da28ad1..87db21f 100644
--- a/javatests/com/google/gerrit/server/permissions/RefControlTest.java
+++ b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
@@ -1259,6 +1259,11 @@
     }
 
     @Override
+    public Object getCacheKey() {
+      return new Object();
+    }
+
+    @Override
     public Optional<String> getUserName() {
       return Optional.ofNullable(username);
     }
diff --git a/plugins/replication b/plugins/replication
index 7d21e80..011c577 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 7d21e802e5057c2c40201de327a4fa5ef4186ab0
+Subproject commit 011c577ef4ee2149d73db974e0ef2fcd3f66bfcf