Mercurial > hg > monetdb-java
diff src/main/java/org/monetdb/mcl/net/MapiSocket.java @ 533:b75464874130 onclient
Keep better track of whether the server has cancelled the upload
IOExceptions are suppressed by PrintStreams print/println methods.
This means the client may not realize the server cancelled
and we must suppress all further attempts to write.
Also, the end of upload handshake is different if a cancellation occurred.
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Fri, 27 Aug 2021 13:45:38 +0200 (2021-08-27) |
parents | 72007c4f8f8a |
children | c9d88af06d35 |
line wrap: on
line diff
--- a/src/main/java/org/monetdb/mcl/net/MapiSocket.java +++ b/src/main/java/org/monetdb/mcl/net/MapiSocket.java @@ -1194,6 +1194,7 @@ public class MapiSocket { /* cannot (yet public final static int DEFAULT_CHUNK_SIZE = 1024 * 1024; private final int chunkSize; private boolean closed = false; + private boolean serverCancelled = false; private int chunkLeft; private byte[] promptBuffer; @@ -1215,6 +1216,12 @@ public class MapiSocket { /* cannot (yet @Override public void write(int b) throws IOException { + if (serverCancelled) { + // We have already thrown an exception and apparently that has been ignored. + // Probably because they're calling print methods instead of write. + // Throw another one, maybe they'll catch this one. + throw new IOException("Server aborted the upload"); + } handleChunking(); super.write(b); wrote(1); @@ -1227,6 +1234,12 @@ public class MapiSocket { /* cannot (yet @Override public void write(byte[] b, int off, int len) throws IOException { + if (serverCancelled) { + // We have already thrown an exception and apparently that has been ignored. + // Probably because they're calling print methods instead of write. + // Throw another one, maybe they'll catch this one. + throw new IOException("Server aborted the upload"); + } while (len > 0) { handleChunking(); int toWrite = Integer.min(len, chunkLeft); @@ -1247,6 +1260,15 @@ public class MapiSocket { /* cannot (yet if (closed) { return; } + closed = true; + + if (serverCancelled) + closeAfterServerCancelled(); + else + closeAfterSuccesfulUpload(); + } + + private void closeAfterSuccesfulUpload() throws IOException { if (chunkLeft != chunkSize) { // flush pending data flushAndReadPrompt(); @@ -1259,6 +1281,10 @@ public class MapiSocket { /* cannot (yet } } + private void closeAfterServerCancelled() throws IOException { + // nothing to do here, we have already read the error prompt. + } + private void wrote(int i) { chunkLeft -= i; } @@ -1278,6 +1304,9 @@ public class MapiSocket { /* cannot (yet case MORE: return; case FILETRANSFER: + // Note, if the caller is calling print methods instead of write, the IO exception gets hidden. + // This is unfortunate but there's nothing we can do about it. + serverCancelled = true; throw new IOException("Server aborted the upload"); default: throw new IOException("Expected MORE/DONE from server, got " + lineType);