Revert "Convert MergeOp and related classes to use RetryHelper"
This high-level approach fundamentally does not work for submitting
cross-project topics where some projects completely succeed prior to the
first lock failure.
For example, say we are submitting change 1 in project A and change 2 in
project B by clicking "Submit" on change 1. The submit to project A
succeeds, so change 1 is marked as merged, but the submit to project B
fails with a LockFailureException. We then retry the whole Submit#apply
using the normal RetryingRestModifyView magic. Unfortunately, this then
fails with the useless error message "Change 1 is merged".
This behavior is strictly worse than the old behavior of failing with an
opaque error message; at least in the case of an error message, the
server is telling the user that there was an error.
A more subtle approach is needed, and will be implemented in a followup.
This reverts commit 8e2729c091.
The revert is almost total, but required conflict resolution, and left
in a few TODO cleanups.
Change-Id: Ic527d9dc95139b16698795d6d7920032d1e70b48
This commit is contained in:
@@ -74,7 +74,6 @@ import com.google.gerrit.server.util.RequestId;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
@@ -109,10 +108,6 @@ public class MergeOp implements AutoCloseable {
|
||||
|
||||
private static final SubmitRuleOptions SUBMIT_RULE_OPTIONS = SubmitRuleOptions.defaults().build();
|
||||
|
||||
public interface Factory {
|
||||
MergeOp create(BatchUpdate.Factory batchUpdateFactory);
|
||||
}
|
||||
|
||||
public static class CommitStatus {
|
||||
private final ImmutableMap<Change.Id, ChangeData> changes;
|
||||
private final ImmutableSetMultimap<Branch.NameKey, Change.Id> byBranch;
|
||||
@@ -244,6 +239,7 @@ public class MergeOp implements AutoCloseable {
|
||||
@Inject
|
||||
MergeOp(
|
||||
ChangeMessagesUtil cmUtil,
|
||||
BatchUpdate.Factory batchUpdateFactory,
|
||||
InternalUser.Factory internalUserFactory,
|
||||
MergeSuperSet mergeSuperSet,
|
||||
MergeValidators.Factory mergeValidatorsFactory,
|
||||
@@ -252,9 +248,9 @@ public class MergeOp implements AutoCloseable {
|
||||
SubmoduleOp.Factory subOpFactory,
|
||||
MergeOpRepoManager orm,
|
||||
NotifyUtil notifyUtil,
|
||||
TopicMetrics topicMetrics,
|
||||
@Assisted BatchUpdate.Factory batchUpdateFactory) {
|
||||
TopicMetrics topicMetrics) {
|
||||
this.cmUtil = cmUtil;
|
||||
this.batchUpdateFactory = batchUpdateFactory;
|
||||
this.internalUserFactory = internalUserFactory;
|
||||
this.mergeSuperSet = mergeSuperSet;
|
||||
this.mergeValidatorsFactory = mergeValidatorsFactory;
|
||||
@@ -263,7 +259,6 @@ public class MergeOp implements AutoCloseable {
|
||||
this.subOpFactory = subOpFactory;
|
||||
this.orm = orm;
|
||||
this.notifyUtil = notifyUtil;
|
||||
this.batchUpdateFactory = batchUpdateFactory;
|
||||
this.topicMetrics = topicMetrics;
|
||||
}
|
||||
|
||||
@@ -507,7 +502,7 @@ public class MergeOp implements AutoCloseable {
|
||||
List<SubmitStrategy> strategies = getSubmitStrategies(toSubmit, submoduleOp, dryrun);
|
||||
this.allProjects = submoduleOp.getProjectsInOrder();
|
||||
batchUpdateFactory.execute(
|
||||
orm.batchUpdates(batchUpdateFactory, allProjects),
|
||||
orm.batchUpdates(allProjects),
|
||||
new SubmitStrategyListener(submitInput, strategies, commitStatus),
|
||||
submissionId,
|
||||
dryrun);
|
||||
@@ -545,10 +540,6 @@ public class MergeOp implements AutoCloseable {
|
||||
return orm;
|
||||
}
|
||||
|
||||
public BatchUpdate.Factory getBatchUpdateFactory() {
|
||||
return batchUpdateFactory;
|
||||
}
|
||||
|
||||
private List<SubmitStrategy> getSubmitStrategies(
|
||||
Map<Branch.NameKey, BranchBatch> toSubmit, SubmoduleOp submoduleOp, boolean dryrun)
|
||||
throws IntegrationException, NoSuchProjectException, IOException {
|
||||
@@ -585,15 +576,15 @@ public class MergeOp implements AutoCloseable {
|
||||
submoduleOp,
|
||||
dryrun);
|
||||
strategies.add(strategy);
|
||||
strategy.addOps(or.getUpdate(batchUpdateFactory), commitsToSubmit);
|
||||
strategy.addOps(or.getUpdate(), commitsToSubmit);
|
||||
if (submitting.submitType().equals(SubmitType.FAST_FORWARD_ONLY)
|
||||
&& submoduleOp.hasSubscription(branch)) {
|
||||
submoduleOp.addOp(or.getUpdate(batchUpdateFactory), branch);
|
||||
submoduleOp.addOp(or.getUpdate(), branch);
|
||||
}
|
||||
} else {
|
||||
// no open change for this branch
|
||||
// add submodule triggered op into BatchUpdate
|
||||
submoduleOp.addOp(or.getUpdate(batchUpdateFactory), branch);
|
||||
submoduleOp.addOp(or.getUpdate(), branch);
|
||||
}
|
||||
}
|
||||
return strategies;
|
||||
|
||||
@@ -101,7 +101,7 @@ public class MergeOpRepoManager implements AutoCloseable {
|
||||
return rw;
|
||||
}
|
||||
|
||||
public BatchUpdate getUpdate(BatchUpdate.Factory batchUpdateFactory) {
|
||||
public BatchUpdate getUpdate() {
|
||||
checkState(db != null, "call setContext before getUpdate");
|
||||
if (update == null) {
|
||||
update =
|
||||
@@ -149,6 +149,7 @@ public class MergeOpRepoManager implements AutoCloseable {
|
||||
}
|
||||
|
||||
private final Map<Project.NameKey, OpenRepo> openRepos;
|
||||
private final BatchUpdate.Factory batchUpdateFactory;
|
||||
private final OnSubmitValidators.Factory onSubmitValidatorsFactory;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final ProjectCache projectCache;
|
||||
@@ -162,9 +163,11 @@ public class MergeOpRepoManager implements AutoCloseable {
|
||||
MergeOpRepoManager(
|
||||
GitRepositoryManager repoManager,
|
||||
ProjectCache projectCache,
|
||||
BatchUpdate.Factory batchUpdateFactory,
|
||||
OnSubmitValidators.Factory onSubmitValidatorsFactory) {
|
||||
this.repoManager = repoManager;
|
||||
this.projectCache = projectCache;
|
||||
this.batchUpdateFactory = batchUpdateFactory;
|
||||
this.onSubmitValidatorsFactory = onSubmitValidatorsFactory;
|
||||
|
||||
openRepos = new HashMap<>();
|
||||
@@ -199,12 +202,11 @@ public class MergeOpRepoManager implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
public List<BatchUpdate> batchUpdates(
|
||||
BatchUpdate.Factory batchUpdateFactory, Collection<Project.NameKey> projects)
|
||||
public List<BatchUpdate> batchUpdates(Collection<Project.NameKey> projects)
|
||||
throws NoSuchProjectException, IOException {
|
||||
List<BatchUpdate> updates = new ArrayList<>(projects.size());
|
||||
for (Project.NameKey project : projects) {
|
||||
updates.add(getRepo(project).getUpdate(batchUpdateFactory).setRefLogMessage("merged"));
|
||||
updates.add(getRepo(project).getUpdate().setRefLogMessage("merged"));
|
||||
}
|
||||
return updates;
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public class ReceiveCommits {
|
||||
private Map<String, Ref> allRefs;
|
||||
|
||||
private final SubmoduleOp.Factory subOpFactory;
|
||||
private final MergeOp.Factory mergeOpFactory;
|
||||
private final Provider<MergeOp> mergeOpProvider;
|
||||
private final Provider<MergeOpRepoManager> ormProvider;
|
||||
private final DynamicMap<ProjectConfigEntry> pluginConfigEntries;
|
||||
private final NotesMigration notesMigration;
|
||||
@@ -400,7 +400,7 @@ public class ReceiveCommits {
|
||||
@Assisted ProjectControl projectControl,
|
||||
@Assisted Repository repo,
|
||||
SubmoduleOp.Factory subOpFactory,
|
||||
MergeOp.Factory mergeOpFactory,
|
||||
Provider<MergeOp> mergeOpProvider,
|
||||
Provider<MergeOpRepoManager> ormProvider,
|
||||
DynamicMap<ProjectConfigEntry> pluginConfigEntries,
|
||||
NotesMigration notesMigration,
|
||||
@@ -448,7 +448,7 @@ public class ReceiveCommits {
|
||||
this.receiveId = RequestId.forProject(project.getNameKey());
|
||||
|
||||
this.subOpFactory = subOpFactory;
|
||||
this.mergeOpFactory = mergeOpFactory;
|
||||
this.mergeOpProvider = mergeOpProvider;
|
||||
this.ormProvider = ormProvider;
|
||||
this.pluginConfigEntries = pluginConfigEntries;
|
||||
this.notesMigration = notesMigration;
|
||||
@@ -657,7 +657,7 @@ public class ReceiveCommits {
|
||||
try (MergeOpRepoManager orm = ormProvider.get()) {
|
||||
orm.setContext(db, TimeUtil.nowTs(), user, receiveId);
|
||||
SubmoduleOp op = subOpFactory.create(branches, orm);
|
||||
op.updateSuperProjects(batchUpdateFactory);
|
||||
op.updateSuperProjects();
|
||||
} catch (SubmoduleException e) {
|
||||
logError("Can't update the superprojects", e);
|
||||
}
|
||||
@@ -2275,7 +2275,7 @@ public class ReceiveCommits {
|
||||
tipChange, "tip of push does not correspond to a change; found these changes: %s", bySha);
|
||||
logDebug(
|
||||
"Processing submit with tip change {} ({})", tipChange.getId(), magicBranch.cmd.getNewId());
|
||||
try (MergeOp op = mergeOpFactory.create(batchUpdateFactory)) {
|
||||
try (MergeOp op = mergeOpProvider.get()) {
|
||||
op.merge(db, tipChange, user, false, new SubmitInput(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ public class SubmoduleOp {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void updateSuperProjects(BatchUpdate.Factory updateFactory) throws SubmoduleException {
|
||||
public void updateSuperProjects() throws SubmoduleException {
|
||||
ImmutableSet<Project.NameKey> projects = getProjectsInOrder();
|
||||
if (projects == null) {
|
||||
return;
|
||||
@@ -370,15 +370,12 @@ public class SubmoduleOp {
|
||||
// get a new BatchUpdate for the super project
|
||||
OpenRepo or = orm.getRepo(project);
|
||||
for (Branch.NameKey branch : branchesByProject.get(project)) {
|
||||
addOp(or.getUpdate(updateFactory), branch);
|
||||
addOp(or.getUpdate(), branch);
|
||||
}
|
||||
}
|
||||
}
|
||||
batchUpdateFactory.execute(
|
||||
orm.batchUpdates(updateFactory, superProjects),
|
||||
BatchUpdateListener.NONE,
|
||||
orm.getSubmissionId(),
|
||||
false);
|
||||
orm.batchUpdates(superProjects), BatchUpdateListener.NONE, orm.getSubmissionId(), false);
|
||||
} catch (RestApiException | UpdateException | IOException | NoSuchProjectException e) {
|
||||
throw new SubmoduleException("Cannot update gitlinks", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user