jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jukka Zitting <jukka.zitt...@gmail.com>
Subject Re: Conflict handling through rebasing branches
Date Fri, 18 Jan 2013 09:57:13 GMT
Hi,

On Thu, Jan 17, 2013 at 7:15 PM, Michael Dürig <mduerig@apache.org> wrote:
> int merge(branch) {
>     while(true) {
>         if (!rebase(branch)) {
>             throw new MicroKernelException("merge conflict");
>         }
>
>         atomic {
>             if (branch.baseRevision == trunk.headRevision) {
>                 trunk.headRevision = branch.headRevision
>                 return trunk.headRevision;
>             }
>         }
>     }
> }

One thing that came up already earlier, but should be reiterated here:
We have commit hooks that update indexes and possibly other
repository-wide content structures. It is quite likely for these to
cause merge conflicts. Also, the rebase operation may end up
invalidating some content constraints, so it should be possible to
re-run validators between the rebase operation and the final
headRevision update.

Another, more minor point is that the loop above will behave badly if
the system is already overloaded and can't process merges as fast as
requested. A retry limit that causes the operation to fail after a
fixed amount of time would be safer.

Thus I propose the following update to the logic:

    int merge(branch) {
        for (int i = 0; i < MAX_REBASE_COUNT; i++) {
            if (!rebase(branch)) {
                throw new CommitFailedException("conflict");
            }

            runCommitHooks(branch);

            atomic {
                if (branch.baseRevision == trunk.headRevision) {
                     trunk.headRevision = branch.headRevision;
                     return trunk.headRevision;
                 }
             }
        }
        throw new CommitFailedException("too busy");
    }

The trouble here is that the commit hooks are in oak-core, so we'd
need to have oak-core instead of the MicroKernel be in charge of this
coordinating this work. One way of doing it would be to expose the
rebase() operation as a part of the MicroKernel API and to require
merge() and commit() to simply reject all changes that aren't based on
the latest head revision.

BR,

Jukka Zitting

Mime
View raw message