From 7d513afb48e6e7710ecaed814b4a6e8d7bac2ab4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sun, 13 Sep 2015 16:33:47 +0200 Subject: [server] Limit hashqueue length depending on max mem --- .../bwlp/sat/fileserv/IncomingDataTransfer.java | 20 ++++++++++++++++++-- .../java/org/openslx/bwlp/sat/util/Constants.java | 11 ++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java index fa8647d9..6ffe6bdc 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java @@ -113,7 +113,7 @@ public class IncomingDataTransfer extends AbstractTransfer implements HashCheckC static { HashChecker hc; try { - hc = new HashChecker("SHA-1"); + hc = new HashChecker("SHA-1", Constants.HASHCHECK_QUEUE_LEN); } catch (NoSuchAlgorithmException e) { hc = null; } @@ -433,7 +433,23 @@ public class IncomingDataTransfer extends AbstractTransfer implements HashCheckC Thread.currentThread().interrupt(); return null; } - buffer = new byte[buffer.length]; + try { + buffer = new byte[buffer.length]; + } catch (OutOfMemoryError e) { + // Usually catching OOM errors is a bad idea, but it's quite safe here as + // we know exactly where it happened, no hidden sub-calls through 20 objects. + // The most likely cause here is that the hash checker/disk cannot keep up + // writing out completed chunks, so we just sleep a bit and try again. If it still + // fails, we exit completely. + try { + Thread.sleep(6000); + } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); + return null; + } + // Might raise OOM again, but THIS TIME I MEAN IT + buffer = new byte[buffer.length]; + } } else { writeFileData(currentChunk.range.startOffset, currentChunk.range.getLength(), buffer); chunks.markSuccessful(currentChunk); diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java index 55a87b5f..e45273db 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java @@ -11,13 +11,15 @@ public class Constants { private static final Logger LOGGER = Logger.getLogger(Constants.class); - public static final String INCOMPLETE_UPLOAD_SUFFIX = ".part"; + public static final String INCOMPLETE_UPLOAD_SUFFIX = ".upload.partial"; public static final int MAX_UPLOADS; public static final int MAX_DOWNLOADS; public static final int MAX_MASTER_UPLOADS = 2; public static final int MAX_MASTER_DOWNLOADS = 3; public static final int TRANSFER_TIMEOUT = 15 * 1000; // 15s + public static final int HASHCHECK_QUEUE_LEN; + static { long maxMem = Runtime.getRuntime().maxMemory(); if (maxMem == Long.MAX_VALUE) { @@ -48,5 +50,12 @@ public class Constants { MAX_UPLOADS = (int) Math.max(1, (maxMem - 64) / (FileChunk.CHUNK_SIZE_MIB * 2)); MAX_DOWNLOADS = MAX_UPLOADS * 2; + int hashQueueLen = (int) (maxMem / 100); + if (hashQueueLen < 1) { + hashQueueLen = 1; + } else if (hashQueueLen > 6) { + hashQueueLen = 6; + } + HASHCHECK_QUEUE_LEN = hashQueueLen; } } -- cgit v1.2.3-55-g7522