]> source.dussan.org Git - jgit.git/commitdiff
Show resolving deltas progress to push clients 82/2382/1
authorShawn O. Pearce <spearce@spearce.org>
Mon, 31 Jan 2011 15:07:05 +0000 (07:07 -0800)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 31 Jan 2011 20:31:52 +0000 (12:31 -0800)
CGit push clients 1.6.6 and later support progress messages on the
side-band-64k channel during push, as this was introduced to handle
server side hook errors reported over smart HTTP.

Since JGit's delta resolution isn't always as fast as CGit's is,
a user may think the server has crashed and failed to report
status if the user pushed a lot of content and sees no feedback.
Exposing the progress monitor during the resolving deltas phase
will let the user know the server is still making forward progress.

This also helps BasePackPushConnection, which has a bounded timeout
on how long it will wait before assuming the remote server is dead.
Progress messages pushed down the side-band channel will reset the
read timer, helping the connection to stay alive and avoid timing
out before the remote side's work is complete.

Change-Id: I429c825e5a724d2f21c66f95526d9c49edcc6ca9
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryPackParser.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java

index b13df8108c2f886c624d6771edf80f3ce405545c..d8df339d5eca15b6ae76a73104127c82fe0136f1 100644 (file)
@@ -168,13 +168,14 @@ public class ObjectDirectoryPackParser extends PackParser {
        }
 
        @Override
-       public PackLock parse(ProgressMonitor progress) throws IOException {
+       public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
+                       throws IOException {
                tmpPack = File.createTempFile("incoming_", ".pack", db.getDirectory());
                tmpIdx = new File(db.getDirectory(), baseName(tmpPack) + ".idx");
                try {
                        out = new RandomAccessFile(tmpPack, "rw");
 
-                       super.parse(progress);
+                       super.parse(receiving, resolving);
 
                        out.seek(packEnd);
                        out.write(packHash);
index 9d75328af484fd28feecccb46cc8000cca6419ec..bae01f17d26cf2a4e7dda6d6cb486ff67dcaa8da 100644 (file)
@@ -406,10 +406,33 @@ public abstract class PackParser {
         * @throws IOException
         *             the stream is malformed, or contains corrupt objects.
         */
-       public PackLock parse(ProgressMonitor progress) throws IOException {
-               if (progress == null)
-                       progress = NullProgressMonitor.INSTANCE;
-               progress.start(2 /* tasks */);
+       public final PackLock parse(ProgressMonitor progress) throws IOException {
+               return parse(progress, progress);
+       }
+
+       /**
+        * Parse the pack stream.
+        *
+        * @param receiving
+        *            receives progress feedback during the initial receiving
+        *            objects phase. If null, {@link NullProgressMonitor} will be
+        *            used.
+        * @param resolving
+        *            receives progress feedback during the resolving objects phase.
+        * @return the pack lock, if one was requested by setting
+        *         {@link #setLockMessage(String)}.
+        * @throws IOException
+        *             the stream is malformed, or contains corrupt objects.
+        */
+       public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
+                       throws IOException {
+               if (receiving == null)
+                       receiving = NullProgressMonitor.INSTANCE;
+               if (resolving == null)
+                       resolving = NullProgressMonitor.INSTANCE;
+
+               if (receiving == resolving)
+                       receiving.start(2 /* tasks */);
                try {
                        readPackHeader();
 
@@ -418,21 +441,25 @@ public abstract class PackParser {
                        baseByPos = new LongMap<UnresolvedDelta>();
                        deferredCheckBlobs = new ArrayList<PackedObjectInfo>();
 
-                       progress.beginTask(JGitText.get().receivingObjects,
+                       receiving.beginTask(JGitText.get().receivingObjects,
                                        (int) objectCount);
-                       for (int done = 0; done < objectCount; done++) {
-                               indexOneObject();
-                               progress.update(1);
-                               if (progress.isCancelled())
-                                       throw new IOException(JGitText.get().downloadCancelled);
+                       try {
+                               for (int done = 0; done < objectCount; done++) {
+                                       indexOneObject();
+                                       receiving.update(1);
+                                       if (receiving.isCancelled())
+                                               throw new IOException(JGitText.get().downloadCancelled);
+                               }
+                               readPackFooter();
+                               endInput();
+                       } finally {
+                               receiving.endTask();
                        }
-                       readPackFooter();
-                       endInput();
+
                        if (!deferredCheckBlobs.isEmpty())
                                doDeferredCheckBlobs();
-                       progress.endTask();
                        if (deltaCount > 0) {
-                               resolveDeltas(progress);
+                               resolveDeltas(resolving);
                                if (entryCount < objectCount) {
                                        if (!isAllowThin()) {
                                                throw new IOException(MessageFormat.format(JGitText
@@ -440,7 +467,7 @@ public abstract class PackParser {
                                                                (objectCount - entryCount)));
                                        }
 
-                                       resolveDeltasWithExternalBases(progress);
+                                       resolveDeltasWithExternalBases(resolving);
 
                                        if (entryCount < objectCount) {
                                                throw new IOException(MessageFormat.format(JGitText
@@ -467,8 +494,6 @@ public abstract class PackParser {
                                inflater = null;
                                objectDatabase.close();
                        }
-
-                       progress.endTask();
                }
                return null; // By default there is no locking.
        }
index 8c50604f13860aa5d0404e2532b66c2c0530b523..59037c3bd77942eb4142cf5a0d426733fcc9da59 100644 (file)
@@ -77,6 +77,7 @@ import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectIdSubclassMap;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.ProgressMonitor;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
@@ -162,6 +163,8 @@ public class ReceivePack {
 
        private Writer msgs;
 
+       private SideBandOutputStream msgOut;
+
        private PackParser parser;
 
        /** The refs we advertised as existing at the start of the connection. */
@@ -758,9 +761,9 @@ public class ReceivePack {
                        OutputStream out = rawOut;
 
                        rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
+                       msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
                        pckOut = new PacketLineOut(rawOut);
-                       msgs = new OutputStreamWriter(new SideBandOutputStream(CH_PROGRESS,
-                                       MAX_BUF, out), Constants.CHARSET);
+                       msgs = new OutputStreamWriter(msgOut, Constants.CHARSET);
                }
        }
 
@@ -780,6 +783,11 @@ public class ReceivePack {
                if (timeoutIn != null)
                        timeoutIn.setTimeout(10 * timeout * 1000);
 
+               ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
+               ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
+               if (sideBand)
+                       resolving = new SideBandProgressMonitor(msgOut);
+
                ObjectInserter ins = db.newObjectInserter();
                try {
                        String lockMsg = "jgit receive-pack";
@@ -792,7 +800,7 @@ public class ReceivePack {
                        parser.setNeedBaseObjectIds(checkReferencedIsReachable);
                        parser.setObjectChecking(isCheckReceivedObjects());
                        parser.setLockMessage(lockMsg);
-                       packLock = parser.parse(NullProgressMonitor.INSTANCE);
+                       packLock = parser.parse(receiving, resolving);
                        ins.flush();
                } finally {
                        ins.release();