use of com.google.gerrit.server.notedb.NoteDbUpdateManager in project gerrit by GerritCodeReview.
the class UnfusedNoteDbBatchUpdate method executeChangeOps.
private Map<Change.Id, ChangeResult> executeChangeOps(boolean dryrun) throws Exception {
logDebug("Executing change ops");
Map<Change.Id, ChangeResult> result = Maps.newLinkedHashMapWithExpectedSize(ops.keySet().size());
initRepository();
Repository repo = repoView.getRepository();
// update as in executeUpdateRepo.
try (ObjectInserter ins = repo.newObjectInserter();
ObjectReader reader = ins.newReader();
RevWalk rw = new RevWalk(reader);
NoteDbUpdateManager updateManager = updateManagerFactory.create(project).setChangeRepo(repo, rw, ins, new ChainedReceiveCommands(repo))) {
if (user.isIdentifiedUser()) {
updateManager.setRefLogIdent(user.asIdentifiedUser().newRefLogIdent(when, tz));
}
for (Map.Entry<Change.Id, Collection<BatchUpdateOp>> e : ops.asMap().entrySet()) {
Change.Id id = e.getKey();
ChangeContextImpl ctx = newChangeContext(id);
boolean dirty = false;
logDebug("Applying {} ops for change {}", e.getValue().size(), id);
for (BatchUpdateOp op : e.getValue()) {
dirty |= op.updateChange(ctx);
}
if (!dirty) {
logDebug("No ops reported dirty, short-circuiting");
result.put(id, ChangeResult.SKIPPED);
continue;
}
for (ChangeUpdate u : ctx.updates.values()) {
updateManager.add(u);
}
if (ctx.deleted) {
logDebug("Change {} was deleted", id);
updateManager.deleteChange(id);
result.put(id, ChangeResult.DELETED);
} else {
result.put(id, ChangeResult.UPSERTED);
}
}
if (!dryrun) {
logDebug("Executing NoteDb updates");
updateManager.execute();
}
}
return result;
}
use of com.google.gerrit.server.notedb.NoteDbUpdateManager in project gerrit by GerritCodeReview.
the class RebuildNoteDb method rebuildProject.
private boolean rebuildProject(ReviewDb db, ImmutableListMultimap<Project.NameKey, Change.Id> allChanges, Project.NameKey project, Repository allUsersRepo) throws IOException, OrmException {
checkArgument(allChanges.containsKey(project));
boolean ok = true;
ProgressMonitor pm = new TextProgressMonitor(new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out, UTF_8))));
pm.beginTask(FormatUtil.elide(project.get(), 50), allChanges.get(project).size());
try (NoteDbUpdateManager manager = updateManagerFactory.create(project);
ObjectInserter allUsersInserter = allUsersRepo.newObjectInserter();
ObjectReader reader = allUsersInserter.newReader();
RevWalk allUsersRw = new RevWalk(reader)) {
manager.setAllUsersRepo(allUsersRepo, allUsersRw, allUsersInserter, new ChainedReceiveCommands(allUsersRepo));
for (Change.Id changeId : allChanges.get(project)) {
try {
rebuilder.buildUpdates(manager, bundleReader.fromReviewDb(db, changeId));
} catch (NoPatchSetsException e) {
log.warn(e.getMessage());
} catch (Throwable t) {
log.error("Failed to rebuild change " + changeId, t);
ok = false;
}
pm.update(1);
}
manager.execute();
} finally {
pm.endTask();
}
return ok;
}
use of com.google.gerrit.server.notedb.NoteDbUpdateManager in project gerrit by GerritCodeReview.
the class ReviewDbBatchUpdate method executeNoteDbUpdates.
private void executeNoteDbUpdates(List<ChangeTask> tasks) throws ResourceConflictException, IOException {
// Aggregate together all NoteDb ref updates from the ops we executed,
// possibly in parallel. Each task had its own NoteDbUpdateManager instance
// with its own thread-local copy of the repo(s), but each of those was just
// used for staging updates and was never executed.
//
// Use a new BatchRefUpdate as the original batchRefUpdate field is intended
// for use only by the updateRepo phase.
//
// See the comments in NoteDbUpdateManager#execute() for why we execute the
// updates on the change repo first.
logDebug("Executing NoteDb updates for {} changes", tasks.size());
try {
initRepository();
BatchRefUpdate changeRefUpdate = repoView.getRepository().getRefDatabase().newBatchUpdate();
boolean hasAllUsersCommands = false;
try (ObjectInserter ins = repoView.getRepository().newObjectInserter()) {
int objs = 0;
for (ChangeTask task : tasks) {
if (task.noteDbResult == null) {
logDebug("No-op update to {}", task.id);
continue;
}
for (ReceiveCommand cmd : task.noteDbResult.changeCommands()) {
changeRefUpdate.addCommand(cmd);
}
for (InsertedObject obj : task.noteDbResult.changeObjects()) {
objs++;
ins.insert(obj.type(), obj.data().toByteArray());
}
hasAllUsersCommands |= !task.noteDbResult.allUsersCommands().isEmpty();
}
logDebug("Collected {} objects and {} ref updates to change repo", objs, changeRefUpdate.getCommands().size());
executeNoteDbUpdate(getRevWalk(), ins, changeRefUpdate);
}
if (hasAllUsersCommands) {
try (Repository allUsersRepo = repoManager.openRepository(allUsers);
RevWalk allUsersRw = new RevWalk(allUsersRepo);
ObjectInserter allUsersIns = allUsersRepo.newObjectInserter()) {
int objs = 0;
BatchRefUpdate allUsersRefUpdate = allUsersRepo.getRefDatabase().newBatchUpdate();
for (ChangeTask task : tasks) {
for (ReceiveCommand cmd : task.noteDbResult.allUsersCommands()) {
allUsersRefUpdate.addCommand(cmd);
}
for (InsertedObject obj : task.noteDbResult.allUsersObjects()) {
allUsersIns.insert(obj.type(), obj.data().toByteArray());
}
}
logDebug("Collected {} objects and {} ref updates to All-Users", objs, allUsersRefUpdate.getCommands().size());
executeNoteDbUpdate(allUsersRw, allUsersIns, allUsersRefUpdate);
}
} else {
logDebug("No All-Users updates");
}
} catch (IOException e) {
if (tasks.stream().allMatch(t -> t.storage == PrimaryStorage.REVIEW_DB)) {
// Ignore all errors trying to update NoteDb at this point. We've already written the
// NoteDbChangeStates to ReviewDb, which means if any state is out of date it will be
// rebuilt the next time it is needed.
//
// Always log even without RequestId.
log.debug("Ignoring NoteDb update error after ReviewDb write", e);
// Otherwise, we can't prove it's safe to ignore the error, either because some change had
// NOTE_DB primary, or a task failed before determining the primary storage.
} else if (e instanceof LockFailureException) {
// although it happened too late for us to produce anything but a generic error message.
throw new ResourceConflictException("Updating change failed due to conflicting write", e);
}
throw e;
}
}
use of com.google.gerrit.server.notedb.NoteDbUpdateManager in project gerrit by GerritCodeReview.
the class ChangeRebuilderImpl method rebuild.
private Result rebuild(ReviewDb db, Change.Id changeId, boolean checkReadOnly) throws IOException, OrmException {
db = ReviewDbUtil.unwrapDb(db);
// Read change just to get project; this instance is then discarded so we
// can read a consistent ChangeBundle inside a transaction.
Change change = db.changes().get(changeId);
if (change == null) {
throw new NoSuchChangeException(changeId);
}
try (NoteDbUpdateManager manager = updateManagerFactory.create(change.getProject())) {
buildUpdates(manager, bundleReader.fromReviewDb(db, changeId));
return execute(db, changeId, manager, checkReadOnly);
}
}
use of com.google.gerrit.server.notedb.NoteDbUpdateManager in project gerrit by GerritCodeReview.
the class ChangeRebuilderImpl method stage.
@Override
public NoteDbUpdateManager stage(ReviewDb db, Change.Id changeId) throws IOException, OrmException {
db = ReviewDbUtil.unwrapDb(db);
Change change = checkNoteDbState(ChangeNotes.readOneReviewDbChange(db, changeId));
if (change == null) {
throw new NoSuchChangeException(changeId);
}
NoteDbUpdateManager manager = updateManagerFactory.create(change.getProject());
buildUpdates(manager, bundleReader.fromReviewDb(db, changeId));
manager.stage();
return manager;
}
Aggregations