|
@@ -22,9 +22,12 @@ import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.io.OutputStream;
|
|
|
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+
|
|
|
|
+import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.fs.StreamCapabilities;
|
|
import org.apache.hadoop.fs.StreamCapabilities;
|
|
import org.apache.hadoop.fs.Syncable;
|
|
import org.apache.hadoop.fs.Syncable;
|
|
-import org.apache.hadoop.classification.InterfaceAudience;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Support the Syncable interface on top of a DataOutputStream.
|
|
* Support the Syncable interface on top of a DataOutputStream.
|
|
@@ -35,6 +38,8 @@ import org.apache.hadoop.classification.InterfaceAudience;
|
|
public class SyncableDataOutputStream extends DataOutputStream
|
|
public class SyncableDataOutputStream extends DataOutputStream
|
|
implements Syncable, StreamCapabilities {
|
|
implements Syncable, StreamCapabilities {
|
|
|
|
|
|
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(SyncableDataOutputStream.class);
|
|
|
|
+
|
|
public SyncableDataOutputStream(OutputStream out) {
|
|
public SyncableDataOutputStream(OutputStream out) {
|
|
super(out);
|
|
super(out);
|
|
}
|
|
}
|
|
@@ -70,4 +75,34 @@ public class SyncableDataOutputStream extends DataOutputStream
|
|
((Syncable) out).hsync();
|
|
((Syncable) out).hsync();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void close() throws IOException {
|
|
|
|
+ IOException ioeFromFlush = null;
|
|
|
|
+ try {
|
|
|
|
+ flush();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ ioeFromFlush = e;
|
|
|
|
+ throw e;
|
|
|
|
+ } finally {
|
|
|
|
+ try {
|
|
|
|
+ this.out.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ // If there was an Exception during flush(), the Azure SDK will throw back the
|
|
|
|
+ // same when we call close on the same stream. When try and finally both throw
|
|
|
|
+ // Exception, Java will use Throwable#addSuppressed for one of the Exception so
|
|
|
|
+ // that the caller will get one exception back. When within this, if both
|
|
|
|
+ // Exceptions are equal, it will throw back IllegalStateException. This makes us
|
|
|
|
+ // to throw back a non IOE. The below special handling is to avoid this.
|
|
|
|
+ if (ioeFromFlush == e) {
|
|
|
|
+ // Do nothing..
|
|
|
|
+ // The close() call gave back the same IOE which flush() gave. Just swallow it
|
|
|
|
+ LOG.debug("flush() and close() throwing back same Exception. Just swallowing the latter", e);
|
|
|
|
+ } else {
|
|
|
|
+ // Let Java handle 2 different Exceptions been thrown from try and finally.
|
|
|
|
+ throw e;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|