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:
Dave Borowitz
2017-06-14 15:19:45 -04:00
parent 6c06b54f05
commit be2be20c83
7 changed files with 63 additions and 102 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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);
}