Changeset: 8fc3225c9198 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8fc3225c9198 Modified Files: Branch: default Log Message:
Merged from Dec2011 diffs (225 lines): diff --git a/java/ChangeLog.Dec2011 b/java/ChangeLog.Dec2011 --- a/java/ChangeLog.Dec2011 +++ b/java/ChangeLog.Dec2011 @@ -1,3 +1,7 @@ # ChangeLog file for java # This file is updated with Maddlog +* Tue Feb 14 2012 Fabian Groffen <[email protected]> +- Resolved a bug where JDBC and Control connections could terminate + abruptly with 'Connection closed' messages + diff --git a/java/src/nl/cwi/monetdb/client/JMonetDB.java b/java/src/nl/cwi/monetdb/client/JMonetDB.java --- a/java/src/nl/cwi/monetdb/client/JMonetDB.java +++ b/java/src/nl/cwi/monetdb/client/JMonetDB.java @@ -59,12 +59,9 @@ public class JMonetDB { "Use the given hash algorithm during challenge response. " + "Supported algorithm names: SHA256, SHA1, MD5."); // arguments which can have zero or one argument(s) - copts.addOption(null, "Xdebug", CmdLineOpts.CAR_ZERO_ONE, null, + copts.addOption(null, "Xdebug", CmdLineOpts.CAR_ONE, null, "Writes a transmission log to disk for debugging purposes. " + - "If a file name is given, it is used, otherwise a file " + - "called monet<timestamp>.log is created. A given file " + - "never be overwritten; instead a unique variation of the " + - "file is used."); + "A file name must be given."); try { copts.processArgs(args); @@ -133,6 +130,11 @@ copts.produceHelpMessage() } // FIXME: Control needs to respect Xhash + if (copts.getOption("Xdebug").isPresent()) { + String fname = copts.getOption("Xdebug").getArgument(); + ctl.setDebug(fname); + } + String[] commands = copts.getOption("command").getArguments(); if (commands[0].equals("status")) { List<SabaothDB> sdbs; diff --git a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java --- a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java +++ b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java @@ -795,10 +795,12 @@ public final class MapiSocket { * on the BufferedInputStream. We want to benefit from the * Buffered pre-fetching, but not dealing with half blocks. * Changing this class to be able to use the partially received - * data will greatly complicate matters, while an performance + * data will greatly complicate matters, while a performance * improvement is debatable given the relatively small size of * our blocks. Maybe it does speed up on slower links, then * consider this method a quick bug fix/workaround. + * + * @return false if reading the block failed due to EOF */ private boolean _read(byte[] b, int len) throws IOException { int s; @@ -818,6 +820,8 @@ public final class MapiSocket { con.getInetAddress().getHostName() + ":" + con.getPort() + ": Incomplete block read from stream"); } + if (debug) + logRd("server closed the connection (EOF)"); return(false); } len -= s; @@ -850,12 +854,10 @@ public final class MapiSocket { * If the stream is not positioned correctly, hell will break * loose. */ - private void readBlock() throws IOException { + private int readBlock() throws IOException { // read next two bytes (short) - if (!_read(blklen, 2)) throw - new IOException("Read from " + - con.getInetAddress().getHostName() + ":" + - con.getPort() + ": End of stream reached"); + if (!_read(blklen, 2)) + return(-1); // Get the short-value and store its value in blockLen. blockLen = (short)( @@ -879,13 +881,10 @@ public final class MapiSocket { "larger than BLOCKsize: " + blockLen + " > " + block.length); if (!_read(block, blockLen)) - new IOException("Read from " + - con.getInetAddress().getHostName() + ":" + - con.getPort() + ": End of stream reached"); + return(-1); - if (debug) { + if (debug) logRx(new String(block, 0, blockLen, "UTF-8")); - } // if this is the last block, make it end with a newline and // prompt @@ -900,13 +899,19 @@ public final class MapiSocket { if (debug) logRd("inserting prompt"); } + + return(blockLen); } public int read() throws IOException { - if (available() == 0) - readBlock(); + if (available() == 0) { + if (readBlock() == -1) + return(-1); + } + if (debug) logRx(new String(block, readPos, 1, "UTF-8")); + return((int)block[readPos++]); } @@ -915,22 +920,19 @@ public final class MapiSocket { } public int read(byte[] b, int off, int len) throws IOException { - int t = available(); - boolean hasAvailable = t + super.available() > 0; + int t; int size = 0; while (size < len) { + t = available(); if (t == 0) { - if (hasAvailable || size == 0) { - // shortcut some instructions, but make sure we - // always read *something* (block) for a read - // call, unless size == 0 - readBlock(); - t = available(); - } else { - // nothing here, nothing waiting return what we - // have + if (size != 0) + break; + if (readBlock() == -1) { + if (size == 0) + size = -1; break; } + t = available(); } if (len > t) { System.arraycopy(block, readPos, b, off, t); @@ -944,8 +946,6 @@ public final class MapiSocket { size += len; break; } - t = available(); - hasAvailable = t + super.available() > 0; } return(size); } diff --git a/java/src/nl/cwi/monetdb/merovingian/Control.java b/java/src/nl/cwi/monetdb/merovingian/Control.java --- a/java/src/nl/cwi/monetdb/merovingian/Control.java +++ b/java/src/nl/cwi/monetdb/merovingian/Control.java @@ -60,6 +60,8 @@ public class Control { private final int port; /** The passphrase to use when connecting */ private final String passphrase; + /** The file we should write MapiSocket debuglog to */ + private String debug; /** @@ -76,6 +78,18 @@ public class Control { this.passphrase = passphrase; } + /** + * Instructs to write a MCL protocol debug log to the given file. + * This affects any newly performed command, and can be changed + * inbetween commands. Passing null to this method disables the + * debug log. + * + * @param filename the filename to write debug information to, or null + */ + public void setDebug(String filename) { + this.debug = filename; + } + private String controlHash(String pass, String salt) { long ho; long h = 0; @@ -115,11 +129,16 @@ public class Control { MapiSocket ms = new MapiSocket(); ms.setDatabase("merovingian"); ms.setLanguage("control"); - ms.debug("test.log"); + if (debug != null) + ms.debug(debug); try { ms.connect(host, port, "monetdb", passphrase); min = ms.getReader(); mout = ms.getWriter(); + } catch (MCLParseException e) { + throw new MerovingianException(e.getMessage()); + } catch (MCLException e) { + throw new MerovingianException(e.getMessage()); } catch (AssertionError e) { // mcl panics ms.close(); @@ -191,13 +210,9 @@ public class Control { out.close(); s.close(); } - } catch (MCLException e) { - throw new MerovingianException(e.getMessage()); - } catch (MCLParseException e) { - throw new MerovingianException(e.getMessage()); } - mout.writeLine(database + " " + command +"\n"); + mout.writeLine(database + " " + command + "\n"); ArrayList<String> l = new ArrayList<String>(); String tmpLine = min.readLine(); int linetype = min.getLineType(); _______________________________________________ Checkin-list mailing list [email protected] http://mail.monetdb.org/mailman/listinfo/checkin-list
