Trigger GitReferenceUpdated event when account or change sequence is updated
This allows to replicate updates to the refs/sequences/* branches in All-Users and All-Projects. Replicating these refs is not needed for Gerrit slaves (since they do not create new accounts or changes) but replicating these refs may be wanted if the replication target is a Gerrit backup server. Change-Id: Ib1d21a646d89b2e774dc9d50574eb990b8d79ece Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
parent
02e281d9d3
commit
54c04d380d
|
@ -252,7 +252,8 @@ public class AccountIT extends AbstractDaemonTest {
|
|||
Account.Id accountId = create(2); // account creation + external ID creation
|
||||
refUpdateCounter.assertRefUpdateFor(
|
||||
RefUpdateCounter.projectRef(allUsers, RefNames.refsUsers(accountId)),
|
||||
RefUpdateCounter.projectRef(allUsers, RefNames.REFS_EXTERNAL_IDS));
|
||||
RefUpdateCounter.projectRef(allUsers, RefNames.REFS_EXTERNAL_IDS),
|
||||
RefUpdateCounter.projectRef(allUsers, RefNames.REFS_SEQUENCES + Sequences.NAME_ACCOUNTS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -264,6 +265,9 @@ public class AccountIT extends AbstractDaemonTest {
|
|||
RefUpdateCounter.projectRef(allUsers, RefNames.refsUsers(accountId)),
|
||||
2,
|
||||
RefUpdateCounter.projectRef(allUsers, RefNames.REFS_EXTERNAL_IDS),
|
||||
1,
|
||||
RefUpdateCounter.projectRef(
|
||||
allUsers, RefNames.REFS_SEQUENCES + Sequences.NAME_ACCOUNTS),
|
||||
1));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package com.google.gerrit.pgm.init.api;
|
|||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.Sequences;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.notedb.RepoSequence;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
@ -40,6 +41,7 @@ public class SequencesOnInit {
|
|||
RepoSequence accountSeq =
|
||||
new RepoSequence(
|
||||
repoManager,
|
||||
GitReferenceUpdated.DISABLED,
|
||||
new Project.NameKey(allUsersName.get()),
|
||||
Sequences.NAME_ACCOUNTS,
|
||||
accountSeed,
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
|||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.AllUsersName;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.notedb.NotesMigration;
|
||||
import com.google.gerrit.server.notedb.RepoSequence;
|
||||
|
@ -64,6 +65,7 @@ public class Sequences {
|
|||
Provider<ReviewDb> db,
|
||||
NotesMigration migration,
|
||||
GitRepositoryManager repoManager,
|
||||
GitReferenceUpdated gitRefUpdated,
|
||||
AllProjectsName allProjects,
|
||||
AllUsersName allUsers,
|
||||
MetricMaker metrics) {
|
||||
|
@ -74,6 +76,7 @@ public class Sequences {
|
|||
accountSeq =
|
||||
new RepoSequence(
|
||||
repoManager,
|
||||
gitRefUpdated,
|
||||
allUsers,
|
||||
NAME_ACCOUNTS,
|
||||
() -> ReviewDb.FIRST_ACCOUNT_ID,
|
||||
|
@ -84,7 +87,8 @@ public class Sequences {
|
|||
RepoSequence.Seed changeSeed = () -> db.get().nextChangeId() + gap;
|
||||
int changeBatchSize = cfg.getInt("noteDb", "changes", "sequenceBatchSize", 20);
|
||||
changeSeq =
|
||||
new RepoSequence(repoManager, allProjects, NAME_CHANGES, changeSeed, changeBatchSize);
|
||||
new RepoSequence(
|
||||
repoManager, gitRefUpdated, allProjects, NAME_CHANGES, changeSeed, changeBatchSize);
|
||||
|
||||
nextIdLatency =
|
||||
metrics.newTimer(
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.google.common.util.concurrent.Runnables;
|
|||
import com.google.gerrit.common.Nullable;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import java.io.IOException;
|
||||
|
@ -86,6 +87,7 @@ public class RepoSequence {
|
|||
private static final Retryer<RefUpdate.Result> RETRYER = retryerBuilder().build();
|
||||
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final GitReferenceUpdated gitRefUpdated;
|
||||
private final Project.NameKey projectName;
|
||||
private final String refName;
|
||||
private final Seed seed;
|
||||
|
@ -103,16 +105,26 @@ public class RepoSequence {
|
|||
|
||||
public RepoSequence(
|
||||
GitRepositoryManager repoManager,
|
||||
GitReferenceUpdated gitRefUpdated,
|
||||
Project.NameKey projectName,
|
||||
String name,
|
||||
Seed seed,
|
||||
int batchSize) {
|
||||
this(repoManager, projectName, name, seed, batchSize, Runnables.doNothing(), RETRYER);
|
||||
this(
|
||||
repoManager,
|
||||
gitRefUpdated,
|
||||
projectName,
|
||||
name,
|
||||
seed,
|
||||
batchSize,
|
||||
Runnables.doNothing(),
|
||||
RETRYER);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
RepoSequence(
|
||||
GitRepositoryManager repoManager,
|
||||
GitReferenceUpdated gitRefUpdated,
|
||||
Project.NameKey projectName,
|
||||
String name,
|
||||
Seed seed,
|
||||
|
@ -120,6 +132,7 @@ public class RepoSequence {
|
|||
Runnable afterReadRef,
|
||||
Retryer<RefUpdate.Result> retryer) {
|
||||
this.repoManager = checkNotNull(repoManager, "repoManager");
|
||||
this.gitRefUpdated = checkNotNull(gitRefUpdated, "gitRefUpdated");
|
||||
this.projectName = checkNotNull(projectName, "projectName");
|
||||
|
||||
checkArgument(
|
||||
|
@ -213,11 +226,15 @@ public class RepoSequence {
|
|||
}
|
||||
|
||||
private void checkResult(RefUpdate.Result result) throws OrmException {
|
||||
if (result != RefUpdate.Result.NEW && result != RefUpdate.Result.FORCED) {
|
||||
if (!refUpdated(result)) {
|
||||
throw new OrmException("failed to update " + refName + ": " + result);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean refUpdated(RefUpdate.Result result) {
|
||||
return result == RefUpdate.Result.NEW || result == RefUpdate.Result.FORCED;
|
||||
}
|
||||
|
||||
private class TryAcquire implements Callable<RefUpdate.Result> {
|
||||
private final Repository repo;
|
||||
private final RevWalk rw;
|
||||
|
@ -275,7 +292,11 @@ public class RepoSequence {
|
|||
}
|
||||
ru.setNewObjectId(newId);
|
||||
ru.setForceUpdate(true); // Required for non-commitish updates.
|
||||
return ru.update(rw);
|
||||
RefUpdate.Result result = ru.update(rw);
|
||||
if (refUpdated(result)) {
|
||||
gitRefUpdated.fire(projectName, ru, null);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ReceiveCommand storeNew(ObjectInserter ins, String name, int val)
|
||||
|
|
|
@ -51,6 +51,7 @@ import com.google.gerrit.server.Sequences;
|
|||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.GerritServerConfigProvider;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.LockFailureException;
|
||||
import com.google.gerrit.server.git.WorkQueue;
|
||||
|
@ -505,6 +506,7 @@ public class NoteDbMigrator implements AutoCloseable {
|
|||
RepoSequence seq =
|
||||
new RepoSequence(
|
||||
repoManager,
|
||||
GitReferenceUpdated.DISABLED,
|
||||
allProjects,
|
||||
Sequences.NAME_CHANGES,
|
||||
// If sequenceGap is 0, this writes into the sequence ref the same ID that is returned
|
||||
|
|
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.schema;
|
|||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.Sequences;
|
||||
import com.google.gerrit.server.config.AllUsersName;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.notedb.RepoSequence;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
@ -42,7 +43,13 @@ public class Schema_155 extends SchemaVersion {
|
|||
@SuppressWarnings("deprecation")
|
||||
RepoSequence.Seed accountSeed = () -> db.nextAccountId();
|
||||
RepoSequence accountSeq =
|
||||
new RepoSequence(repoManager, allUsersName, Sequences.NAME_ACCOUNTS, accountSeed, 1);
|
||||
new RepoSequence(
|
||||
repoManager,
|
||||
GitReferenceUpdated.DISABLED,
|
||||
allUsersName,
|
||||
Sequences.NAME_ACCOUNTS,
|
||||
accountSeed,
|
||||
1);
|
||||
|
||||
// consume one account ID to ensure that the account sequence is initialized in NoteDb
|
||||
accountSeq.next();
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.github.rholder.retry.StopStrategies;
|
|||
import com.google.common.util.concurrent.Runnables;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.testutil.InMemoryRepositoryManager;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import java.io.IOException;
|
||||
|
@ -264,7 +265,14 @@ public class RepoSequenceTest {
|
|||
Runnable afterReadRef,
|
||||
Retryer<RefUpdate.Result> retryer) {
|
||||
return new RepoSequence(
|
||||
repoManager, project, name, () -> start, batchSize, afterReadRef, retryer);
|
||||
repoManager,
|
||||
GitReferenceUpdated.DISABLED,
|
||||
project,
|
||||
name,
|
||||
() -> start,
|
||||
batchSize,
|
||||
afterReadRef,
|
||||
retryer);
|
||||
}
|
||||
|
||||
private ObjectId writeBlob(String sequenceName, String value) {
|
||||
|
|
Loading…
Reference in New Issue