Search in sources :

Example 1 with NoteDbUpdateManager

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;
}
Also used : NoteDbUpdateManager(com.google.gerrit.server.notedb.NoteDbUpdateManager) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) Collection(java.util.Collection) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RequestId(com.google.gerrit.server.util.RequestId) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 2 with NoteDbUpdateManager

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;
}
Also used : ChainedReceiveCommands(com.google.gerrit.server.update.ChainedReceiveCommands) NoteDbUpdateManager(com.google.gerrit.server.notedb.NoteDbUpdateManager) Change(com.google.gerrit.reviewdb.client.Change) TextProgressMonitor(org.eclipse.jgit.lib.TextProgressMonitor) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BufferedWriter(java.io.BufferedWriter) TextProgressMonitor(org.eclipse.jgit.lib.TextProgressMonitor) NullProgressMonitor(org.eclipse.jgit.lib.NullProgressMonitor) ProgressMonitor(org.eclipse.jgit.lib.ProgressMonitor) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) NoPatchSetsException(com.google.gerrit.server.notedb.rebuild.ChangeRebuilder.NoPatchSetsException) OutputStreamWriter(java.io.OutputStreamWriter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) PrintWriter(java.io.PrintWriter)

Example 3 with NoteDbUpdateManager

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;
    }
}
Also used : AllUsersName(com.google.gerrit.server.config.AllUsersName) ChangeControl(com.google.gerrit.server.project.ChangeControl) RequestId(com.google.gerrit.server.util.RequestId) OrmException(com.google.gwtorm.server.OrmException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) Inject(com.google.inject.Inject) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) LoggerFactory(org.slf4j.LoggerFactory) CheckedFuture(com.google.common.util.concurrent.CheckedFuture) PrimaryStorage(com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage) Assisted(com.google.inject.assistedinject.Assisted) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Config(org.eclipse.jgit.lib.Config) InsertedObject(com.google.gerrit.server.git.InsertedObject) ChangeIndexer(com.google.gerrit.server.index.change.ChangeIndexer) Map(java.util.Map) NoteDbUpdateManager(com.google.gerrit.server.notedb.NoteDbUpdateManager) Timer1(com.google.gerrit.metrics.Timer1) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) TimeZone(java.util.TimeZone) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) NullProgressMonitor(org.eclipse.jgit.lib.NullProgressMonitor) Preconditions.checkState(com.google.common.base.Preconditions.checkState) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) ReviewDbWrapper(com.google.gerrit.reviewdb.server.ReviewDbWrapper) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate) MetricMaker(com.google.gerrit.metrics.MetricMaker) NotesMigration(com.google.gerrit.server.notedb.NotesMigration) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) Singleton(com.google.inject.Singleton) MoreExecutors(com.google.common.util.concurrent.MoreExecutors) ReviewDb(com.google.gerrit.reviewdb.server.ReviewDb) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Change(com.google.gerrit.reviewdb.client.Change) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) Stopwatch(com.google.common.base.Stopwatch) MismatchedStateException(com.google.gerrit.server.notedb.NoteDbUpdateManager.MismatchedStateException) Callable(java.util.concurrent.Callable) LockFailureException(com.google.gerrit.server.git.LockFailureException) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Description(com.google.gerrit.metrics.Description) Field(com.google.gerrit.metrics.Field) Comparator.comparing(java.util.Comparator.comparing) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) Project(com.google.gerrit.reviewdb.client.Project) CurrentUser(com.google.gerrit.server.CurrentUser) Logger(org.slf4j.Logger) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Units(com.google.gerrit.metrics.Description.Units) Throwables(com.google.common.base.Throwables) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) SchemaFactory(com.google.gwtorm.server.SchemaFactory) NoteDbChangeState(com.google.gerrit.server.notedb.NoteDbChangeState) ExecutionException(java.util.concurrent.ExecutionException) Collectors.toList(java.util.stream.Collectors.toList) Futures(com.google.common.util.concurrent.Futures) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate) GitRepositoryManager(com.google.gerrit.server.git.GitRepositoryManager) TreeMap(java.util.TreeMap) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Collections(java.util.Collections) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) GitReferenceUpdated(com.google.gerrit.server.extensions.events.GitReferenceUpdated) Repository(org.eclipse.jgit.lib.Repository) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) InsertedObject(com.google.gerrit.server.git.InsertedObject) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) LockFailureException(com.google.gerrit.server.git.LockFailureException) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate)

Example 4 with NoteDbUpdateManager

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);
    }
}
Also used : NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) NoteDbUpdateManager(com.google.gerrit.server.notedb.NoteDbUpdateManager) Change(com.google.gerrit.reviewdb.client.Change)

Example 5 with NoteDbUpdateManager

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;
}
Also used : NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) NoteDbUpdateManager(com.google.gerrit.server.notedb.NoteDbUpdateManager) Change(com.google.gerrit.reviewdb.client.Change)

Aggregations

Change (com.google.gerrit.reviewdb.client.Change)5 NoteDbUpdateManager (com.google.gerrit.server.notedb.NoteDbUpdateManager)5 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)3 RevWalk (org.eclipse.jgit.revwalk.RevWalk)3 ChangeUpdate (com.google.gerrit.server.notedb.ChangeUpdate)2 NoSuchChangeException (com.google.gerrit.server.project.NoSuchChangeException)2 NullProgressMonitor (org.eclipse.jgit.lib.NullProgressMonitor)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Stopwatch (com.google.common.base.Stopwatch)1 Throwables (com.google.common.base.Throwables)1 ImmutableList (com.google.common.collect.ImmutableList)1 CheckedFuture (com.google.common.util.concurrent.CheckedFuture)1 Futures (com.google.common.util.concurrent.Futures)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ListeningExecutorService (com.google.common.util.concurrent.ListeningExecutorService)1 MoreExecutors (com.google.common.util.concurrent.MoreExecutors)1 Nullable (com.google.gerrit.common.Nullable)1 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)1 RestApiException (com.google.gerrit.extensions.restapi.RestApiException)1