From ccd0c0c911b4575539ea46a3efaf219a249ee392 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 14 Jun 2010 12:49:41 -0700 Subject: [PATCH] UploadPack: Permit flushing progress messages under smart HTTP If UploadPack invokes flush() on the output stream we pass it, its most likely the progress messages coming down the side band stream. As pack generation can take a while, we want to push that down at the client as early as we can, to keep the connection alive, and to let the user know we are still working on their behalf. Ensure we dump the temporary buffer whenever flush() is invoked, otherwise the messages don't get sent in a timely fashion to the user agent (in this case, git fetch). We specifically don't implement flush() for ReceivePack right now, as that protocol currently does not provide progress messages to the user, but it does invoke flush several times, as the different streams include '0000' type flush-pkts to denote various end points. Change-Id: I797c90a2c562a416223dc0704785f61ac64e0220 Signed-off-by: Shawn O. Pearce --- .../jgit/http/server/UploadPackServlet.java | 7 ++++++- .../eclipse/jgit/util/TemporaryBuffer.java | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java index 92d41a0ca..6d0d64fc6 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java @@ -107,7 +107,12 @@ public void doPost(final HttpServletRequest req, up.setBiDirectionalPipe(false); rsp.setContentType(RSP_TYPE); - final SmartOutputStream out = new SmartOutputStream(req, rsp); + final SmartOutputStream out = new SmartOutputStream(req, rsp) { + @Override + public void flush() throws IOException { + doFlush(); + } + }; up.upload(getInputStream(req), out, null); out.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 6c421c5f5..101b6056b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -138,6 +138,19 @@ public void write(final byte[] b, int off, int len) throws IOException { overflow.write(b, off, len); } + /** + * Dumps the entire buffer into the overflow stream, and flushes it. + * + * @throws IOException + * the overflow stream cannot be started, or the buffer contents + * cannot be written to it, or it failed to flush. + */ + protected void doFlush() throws IOException { + if (overflow == null) + switchToOverflow(); + overflow.flush(); + } + /** * Copy all bytes remaining on the input stream into this buffer. * @@ -260,6 +273,11 @@ private boolean reachedInCoreLimit() throws IOException { if (blocks.size() * Block.SZ < inCoreLimit) return false; + switchToOverflow(); + return true; + } + + private void switchToOverflow() throws IOException { overflow = overflow(); final Block last = blocks.remove(blocks.size() - 1); @@ -269,7 +287,6 @@ private boolean reachedInCoreLimit() throws IOException { overflow = new BufferedOutputStream(overflow, Block.SZ); overflow.write(last.buffer, 0, last.count); - return true; } public void close() throws IOException {