1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-27 04:22:07 +03:00

Merge pull request #150 from square/jwilson/recover_flush_and_close

Recover from failed flushes and closes too.
This commit is contained in:
Jake Wharton
2013-04-16 22:32:01 -07:00
2 changed files with 64 additions and 4 deletions

View File

@@ -84,15 +84,29 @@ public abstract class FaultRecoveringOutputStream extends OutputStream {
if (closed) {
return; // don't throw; this stream might have been closed on the caller's behalf
}
out.flush();
while (true) {
try {
out.flush();
return;
} catch (IOException e) {
if (!recover(e)) throw e;
}
}
}
@Override public final void close() throws IOException {
if (closed) {
return;
}
out.close();
closed = true;
while (true) {
try {
out.close();
closed = true;
return;
} catch (IOException e) {
if (!recover(e)) throw e;
}
}
}
/**

View File

@@ -47,7 +47,7 @@ public final class FaultRecoveringOutputStreamTest {
}
}
@Test public void successfulRecovery() throws Exception {
@Test public void successfulRecoveryOnWriteFault() throws Exception {
FaultingOutputStream faulting1 = new FaultingOutputStream();
FaultingOutputStream faulting2 = new FaultingOutputStream();
TestFaultRecoveringOutputStream recovering = new TestFaultRecoveringOutputStream(10, faulting1);
@@ -70,6 +70,45 @@ public final class FaultRecoveringOutputStreamTest {
assertEquals("abc", faulting2.receivedUtf8);
}
@Test public void successfulRecoveryOnFlushFault() throws Exception {
FaultingOutputStream faulting1 = new FaultingOutputStream();
FaultingOutputStream faulting2 = new FaultingOutputStream();
TestFaultRecoveringOutputStream recovering = new TestFaultRecoveringOutputStream(10, faulting1);
recovering.replacements.addLast(faulting2);
recovering.write('a');
faulting1.nextFault = "bad weather";
recovering.flush();
assertEquals(Arrays.asList("bad weather"), recovering.exceptionMessages);
assertEquals("a", faulting1.receivedUtf8);
assertEquals("a", faulting2.receivedUtf8);
assertTrue(faulting1.closed);
assertFalse(faulting2.closed);
assertEquals("a", faulting2.flushedUtf8);
// Confirm that new data goes to the new stream.
recovering.write('b');
assertEquals("a", faulting1.receivedUtf8);
assertEquals("ab", faulting2.receivedUtf8);
assertEquals("a", faulting2.flushedUtf8);
}
@Test public void successfulRecoveryOnCloseFault() throws Exception {
FaultingOutputStream faulting1 = new FaultingOutputStream();
FaultingOutputStream faulting2 = new FaultingOutputStream();
TestFaultRecoveringOutputStream recovering = new TestFaultRecoveringOutputStream(10, faulting1);
recovering.replacements.addLast(faulting2);
recovering.write('a');
faulting1.nextFault = "termites";
recovering.close();
assertEquals(Arrays.asList("termites"), recovering.exceptionMessages);
assertEquals("a", faulting1.receivedUtf8);
assertEquals("a", faulting2.receivedUtf8);
assertTrue(faulting1.closed);
assertTrue(faulting2.closed);
}
@Test public void replacementStreamFaultsImmediately() throws Exception {
FaultingOutputStream faulting1 = new FaultingOutputStream();
FaultingOutputStream faulting2 = new FaultingOutputStream();
@@ -145,6 +184,7 @@ public final class FaultRecoveringOutputStreamTest {
static class FaultingOutputStream extends OutputStream {
String receivedUtf8 = "";
String flushedUtf8 = null;
String nextFault;
boolean closed;
@@ -157,8 +197,14 @@ public final class FaultRecoveringOutputStreamTest {
if (nextFault != null) throw new IOException(nextFault);
}
@Override public void flush() throws IOException {
flushedUtf8 = receivedUtf8;
if (nextFault != null) throw new IOException(nextFault);
}
@Override public void close() throws IOException {
closed = true;
if (nextFault != null) throw new IOException(nextFault);
}
}