summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ostrovsky <david@ostrovsky.org>2022-06-28 17:11:52 +0200
committerDavid Ostrovsky <david@ostrovsky.org>2022-06-28 17:11:52 +0200
commit4604bdb864d986bc5c005b34917a788ed8abdd16 (patch)
tree00598d8cf04543b04897fbd014eeec51692deee1
parent973413c69e34e63394109163c71bf86c73a9e691 (diff)
parent5f156a8febabca89b220547641f9c7a93ee89bfa (diff)
Merge branch 'stable-3.0' into stable-3.1
* stable-3.0: Allow async receive-commits to have a thread-local cache Fix RepoRefCache stale checks during NoteDb rebuild Lazy load change notes when submit by push Change-Id: Ie82487167fc84ec543083b018c3fde1b0a041e1d Release-Notes: skip
-rw-r--r--java/com/google/gerrit/server/git/RepoRefCache.java5
-rw-r--r--java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java3
-rw-r--r--java/com/google/gerrit/server/git/receive/ReceiveCommits.java23
3 files changed, 19 insertions, 12 deletions
diff --git a/java/com/google/gerrit/server/git/RepoRefCache.java b/java/com/google/gerrit/server/git/RepoRefCache.java
index c813b8375b..4fa33118f5 100644
--- a/java/com/google/gerrit/server/git/RepoRefCache.java
+++ b/java/com/google/gerrit/server/git/RepoRefCache.java
@@ -136,8 +136,9 @@ public class RepoRefCache implements RefCache {
}
try {
- ObjectId diskId = refdb.exactRef(refName).getObjectId();
- boolean isStale = !Optional.ofNullable(diskId).equals(id);
+ Optional<ObjectId> diskId =
+ Optional.ofNullable(refdb.exactRef(refName)).map(Ref::getObjectId);
+ boolean isStale = !diskId.equals(id);
if (isStale) {
log.atSevere().log(
"Repository "
diff --git a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
index f5c3aa9d43..c68ed30871 100644
--- a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
@@ -33,6 +33,7 @@ import com.google.gerrit.metrics.Histogram1;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.cache.PerThreadCache;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
@@ -133,7 +134,7 @@ public class AsyncReceiveCommits implements PreReceiveHook {
public void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(oldName + "-for-" + name);
- try {
+ try (PerThreadCache threadLocalCache = PerThreadCache.create(null)) {
receiveCommits.processCommands(commands, progress);
} finally {
Thread.currentThread().setName(oldName);
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 3b5b080009..012ba437fb 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -3278,7 +3278,7 @@ class ReceiveCommits {
}
ListMultimap<ObjectId, Ref> byCommit = changeRefsById();
- Map<Change.Key, ChangeNotes> byKey = null;
+ Map<Change.Key, ChangeData> changeDataByKey = null;
List<ReplaceRequest> replaceAndClose = new ArrayList<>();
int existingPatchSets = 0;
@@ -3302,17 +3302,19 @@ class ReceiveCommits {
}
for (String changeId : c.getFooterLines(FooterConstants.CHANGE_ID)) {
- if (byKey == null) {
- byKey = executeIndexQuery(() -> openChangesByKeyByBranch(branch));
+ if (changeDataByKey == null) {
+ changeDataByKey = executeIndexQuery(() -> openChangesByKeyByBranch(branch));
}
- ChangeNotes onto = byKey.get(Change.key(changeId.trim()));
+ ChangeData onto = changeDataByKey.get(Change.key(changeId.trim()));
if (onto != null) {
newPatchSets++;
// Hold onto this until we're done with the walk, as the call to
// req.validate below calls isMergedInto which resets the walk.
- ReplaceRequest req = new ReplaceRequest(onto.getChangeId(), c, cmd, false);
- req.notes = onto;
+ ChangeNotes ontoNotes = onto.notes();
+ ReplaceRequest req =
+ new ReplaceRequest(ontoNotes.getChangeId(), c, cmd, false);
+ req.notes = ontoNotes;
replaceAndClose.add(req);
continue COMMIT;
}
@@ -3384,13 +3386,16 @@ class ReceiveCommits {
}
}
- private Map<Change.Key, ChangeNotes> openChangesByKeyByBranch(BranchNameKey branch) {
+ private Map<Change.Key, ChangeData> openChangesByKeyByBranch(BranchNameKey branch) {
try (TraceTimer traceTimer =
newTimer("openChangesByKeyByBranch", Metadata.builder().branchName(branch.branch()))) {
- Map<Change.Key, ChangeNotes> r = new HashMap<>();
+ Map<Change.Key, ChangeData> r = new HashMap<>();
for (ChangeData cd : queryProvider.get().byBranchOpen(branch)) {
try {
- r.put(cd.change().getKey(), cd.notes());
+ // ChangeData is not materialised into a ChangeNotes for avoiding
+ // to load a potentially large number of changes meta-data into memory
+ // which would cause unnecessary disk I/O, CPU and heap utilisation.
+ r.put(cd.change().getKey(), cd);
} catch (NoSuchChangeException e) {
// Ignore deleted change
}