private void startNewDownloads() { boolean isLimited = true; int currentAllowedDownloadCount = 0; { final int allowedConcurrentDownloads = Core.frostSettings.getIntValue(SettingsClass.DOWNLOAD_MAX_THREADS); if (allowedConcurrentDownloads <= 0) { isLimited = false; } else { int runningDownloads = 0; for (final FrostDownloadItem dlItem : downloadModelItems.values()) { if (!dlItem.isExternal() && dlItem.getState() == FrostDownloadItem.STATE_PROGRESS) { runningDownloads++; } } currentAllowedDownloadCount = allowedConcurrentDownloads - runningDownloads; if (currentAllowedDownloadCount < 0) { currentAllowedDownloadCount = 0; } } } { while (!isLimited || currentAllowedDownloadCount > 0) { final FrostDownloadItem dlItem = FileTransferManager.inst().getDownloadManager().selectNextDownloadItem(); if (dlItem == null) { break; } // start the download if (startDownload(dlItem)) { currentAllowedDownloadCount--; } } } }
@Override public void run() { final int maxAllowedExceptions = 5; int catchedExceptions = 0; while (true) { try { // if there is no work in queue this call waits for a new queue item final ModelItem<?> item = directTransferQueue.getItemFromQueue(); if (item == null) { // paranoia, should never happen Mixed.wait(5 * 1000); continue; } if (item instanceof FrostUploadItem) { // transfer bytes to node final FrostUploadItem ulItem = (FrostUploadItem) item; // FIXME: provide item, state=Transfer to node, % shows progress final String gqid = ulItem.getGqIdentifier(); final boolean doMime; final boolean setTargetFileName; if (ulItem.isSharedFile()) { doMime = false; setTargetFileName = false; } else { doMime = true; setTargetFileName = true; } final NodeMessage answer = fcpTools.startDirectPersistentPut( gqid, ulItem.getFile(), ulItem.getFileName(), doMime, setTargetFileName, ulItem.getCompress(), ulItem.getFreenetCompatibilityMode(), ulItem.getPriority()); if (answer == null) { final String desc = "Could not open a new FCP2 socket for direct put!"; final FcpResultPut result = new FcpResultPut(FcpResultPut.Error, -1, desc, false); FileTransferManager.inst().getUploadManager().notifyUploadFinished(ulItem, result); logger.severe(desc); } else { // wait for an answer, don't start request again directPUTsWithoutAnswer.add(gqid); } directPUTsInProgress.remove(gqid); } else if (item instanceof FrostDownloadItem) { // transfer bytes from node final FrostDownloadItem dlItem = (FrostDownloadItem) item; // FIXME: provide item, state=Transfer from node, % shows progress final String gqid = dlItem.getGqIdentifier(); final File targetFile = new File(dlItem.getDownloadFilename()); final boolean retryNow; NodeMessage answer = null; try { answer = fcpTools.startDirectPersistentGet(gqid, targetFile); } catch (final FileNotFoundException e) { final String msg = "Could not write to " + dlItem.getDownloadFilename() + ": " + e.getMessage(); System.out.println(msg); logger.severe(msg); } if (answer != null) { final FcpResultGet result = new FcpResultGet(true); FileTransferManager.inst() .getDownloadManager() .notifyDownloadFinished(dlItem, result, targetFile); retryNow = false; } else { logger.severe("Could not open a new fcp socket for direct get!"); final FcpResultGet result = new FcpResultGet(false); retryNow = FileTransferManager.inst() .getDownloadManager() .notifyDownloadFinished(dlItem, result, targetFile); } directGETsInProgress.remove(gqid); if (retryNow) { startDownload(dlItem); } } } catch (final Throwable t) { logger.log(Level.SEVERE, "Exception catched", t); catchedExceptions++; } if (catchedExceptions > maxAllowedExceptions) { logger.log(Level.SEVERE, "Stopping DirectTransferThread because of too much exceptions"); break; } } }
/** Apply the states of FcpRequestPut to the FrostUploadItem. */ private void applyState(final FrostUploadItem ulItem, final FcpPersistentPut putReq) { // when cancelled and we expect this, don't set failed; don't even set the old priority! if (ulItem.isInternalRemoveExpected() && putReq.isFailed()) { final int returnCode = putReq.getCode(); if (returnCode == 25) { return; } } if (directPUTsWithoutAnswer.contains(ulItem.getGqIdentifier())) { // we got an answer directPUTsWithoutAnswer.remove(ulItem.getGqIdentifier()); } // apply externally changed priority if (ulItem.getPriority() != putReq.getPriority()) { if (Core.frostSettings.getBoolValue(SettingsClass.FCP2_ENFORCE_FROST_PRIO_FILE_UPLOAD)) { // reset priority with our current value fcpTools.changeRequestPriority(putReq.getIdentifier(), ulItem.getPriority()); } else { // apply to uploaditem ulItem.setPriority(putReq.getPriority()); } } if (!putReq.isProgressSet() && !putReq.isSuccess() && !putReq.isFailed()) { if (ulItem.getState() == FrostUploadItem.STATE_WAITING) { ulItem.setState(FrostUploadItem.STATE_PROGRESS); } return; } if (putReq.isProgressSet()) { final int doneBlocks = putReq.getDoneBlocks(); final int totalBlocks = putReq.getTotalBlocks(); final boolean isFinalized = putReq.isFinalized(); if (totalBlocks > 0) { ulItem.setDoneBlocks(doneBlocks); ulItem.setTotalBlocks(totalBlocks); ulItem.setFinalized(isFinalized); ulItem.fireValueChanged(); } if (ulItem.getState() != FrostUploadItem.STATE_PROGRESS) { ulItem.setState(FrostUploadItem.STATE_PROGRESS); } } if (putReq.isSuccess()) { // maybe progress was not completely sent ulItem.setFinalized(true); if (ulItem.getTotalBlocks() > 0 && ulItem.getDoneBlocks() != ulItem.getTotalBlocks()) { ulItem.setDoneBlocks(ulItem.getTotalBlocks()); } final String chkKey = putReq.getUri(); if (ulItem.isExternal()) { ulItem.setState(FrostUploadItem.STATE_DONE); ulItem.setKey(chkKey); } else { final FcpResultPut result = new FcpResultPut(FcpResultPut.Success, chkKey); FileTransferManager.inst().getUploadManager().notifyUploadFinished(ulItem, result); } } if (putReq.isFailed()) { final String desc = putReq.getCodeDesc(); if (ulItem.isExternal()) { ulItem.setState(FrostUploadItem.STATE_FAILED); ulItem.setErrorCodeDescription(desc); } else { final int returnCode = putReq.getCode(); final boolean isFatal = putReq.isFatal(); final FcpResultPut result; if (returnCode == 9) { result = new FcpResultPut(FcpResultPut.KeyCollision, returnCode, desc, isFatal); } else if (returnCode == 5) { result = new FcpResultPut(FcpResultPut.Retry, returnCode, desc, isFatal); } else { result = new FcpResultPut(FcpResultPut.Error, returnCode, desc, isFatal); } FileTransferManager.inst().getUploadManager().notifyUploadFinished(ulItem, result); } } }
/** Apply the states of FcpRequestGet to the FrostDownloadItem. */ private void applyState(final FrostDownloadItem dlItem, final FcpPersistentGet getReq) { // when cancelled and we expect this, don't set failed; don't even set the old priority! if (dlItem.isInternalRemoveExpected() && getReq.isFailed()) { final int returnCode = getReq.getCode(); if (returnCode == 25) { return; } } applyPriority(dlItem, getReq); if (dlItem.isDirect() != getReq.isDirect()) { dlItem.setDirect(getReq.isDirect()); } if (!getReq.isProgressSet() && !getReq.isSuccess() && !getReq.isFailed()) { if (dlItem.getState() == FrostDownloadItem.STATE_WAITING) { dlItem.setState(FrostDownloadItem.STATE_PROGRESS); } return; } if (getReq.isProgressSet()) { final int doneBlocks = getReq.getDoneBlocks(); final int requiredBlocks = getReq.getRequiredBlocks(); final int totalBlocks = getReq.getTotalBlocks(); final boolean isFinalized = getReq.isFinalized(); if (totalBlocks > 0) { dlItem.setDoneBlocks(doneBlocks); dlItem.setRequiredBlocks(requiredBlocks); dlItem.setTotalBlocks(totalBlocks); dlItem.setFinalized(isFinalized); dlItem.fireValueChanged(); } if (dlItem.getState() != FrostDownloadItem.STATE_PROGRESS) { dlItem.setState(FrostDownloadItem.STATE_PROGRESS); } } if (getReq.isSuccess()) { // maybe progress was not completely sent dlItem.setFinalized(true); if (dlItem.getTotalBlocks() > 0 && dlItem.getDoneBlocks() < dlItem.getRequiredBlocks()) { dlItem.setDoneBlocks(dlItem.getRequiredBlocks()); dlItem.fireValueChanged(); } if (dlItem.isExternal()) { dlItem.setFileSize(getReq.getFilesize()); dlItem.setState(FrostDownloadItem.STATE_DONE); } else { if (dlItem.isDirect()) { maybeEnqueueDirectGet(dlItem, getReq.getFilesize()); } else { final FcpResultGet result = new FcpResultGet(true); final File targetFile = new File(dlItem.getDownloadFilename()); FileTransferManager.inst() .getDownloadManager() .notifyDownloadFinished(dlItem, result, targetFile); } } } if (getReq.isFailed()) { final String desc = getReq.getCodeDesc(); if (dlItem.isExternal()) { dlItem.setState(FrostDownloadItem.STATE_FAILED); dlItem.setErrorCodeDescription(desc); } else { final int returnCode = getReq.getCode(); final boolean isFatal = getReq.isFatal(); final String redirectURI = getReq.getRedirectURI(); final FcpResultGet result = new FcpResultGet(false, returnCode, desc, isFatal, redirectURI); final File targetFile = new File(dlItem.getDownloadFilename()); final boolean retry = FileTransferManager.inst() .getDownloadManager() .notifyDownloadFinished(dlItem, result, targetFile); if (retry) { fcpTools.removeRequest(getReq.getIdentifier()); startDownload(dlItem); // restart immediately } } } }