@Override public double getFetchedBlocks(ObjectContainer container) { if (persistenceType == PERSIST_FOREVER && progressPending != null) container.activate(progressPending, 2); if (progressPending != null) { return progressPending.getFetchedBlocks(); } else return 0; }
@Override public double getSuccessFraction(ObjectContainer container) { if (persistenceType == PERSIST_FOREVER && progressPending != null) container.activate(progressPending, 2); if (progressPending != null) { return progressPending.getFraction(); } else return -1; }
@Override public boolean isTotalFinalized(ObjectContainer container) { if (finished && succeeded) return true; if (progressPending == null) return false; else { if (persistenceType == PERSIST_FOREVER) container.activate(progressPending, 1); return progressPending.isTotalFinalized(); } }
@Override public void requestWasRemoved(ObjectContainer container, ClientContext context) { // if request is still running, send a GetFailed with code=cancelled if (!finished) { synchronized (this) { succeeded = false; finished = true; FetchException cancelled = new FetchException(FetchException.CANCELLED); getFailedMessage = new GetFailedMessage(cancelled, identifier, global); } trySendDataFoundOrGetFailed(null, container); } // notify client that request was removed FCPMessage msg = new PersistentRequestRemovedMessage(getIdentifier(), global); if (persistenceType != PERSIST_CONNECTION) { if (persistenceType == PERSIST_FOREVER) container.activate(client, 1); client.queueClientRequestMessage(msg, 0, container); } freeData(container); if (persistenceType == PERSIST_FOREVER) { container.activate(fctx, 1); if (fctx.allowedMIMETypes != null) { container.activate(fctx.allowedMIMETypes, 5); container.delete(fctx.allowedMIMETypes); } fctx.removeFrom(container); getter.removeFrom(container, context); if (targetFile != null) container.delete(targetFile); if (tempFile != null) container.delete(tempFile); if (getFailedMessage != null) { container.activate(getFailedMessage, 5); getFailedMessage.removeFrom(container); } if (postFetchProtocolErrorMessage != null) { container.activate(postFetchProtocolErrorMessage, 5); postFetchProtocolErrorMessage.removeFrom(container); } if (allDataPending != null) { container.activate(allDataPending, 5); allDataPending.removeFrom(container); } if (progressPending != null) { container.activate(progressPending, 5); progressPending.removeFrom(container); } } super.requestWasRemoved(container, context); }
@Override public boolean restart(ObjectContainer container, ClientContext context) { if (!canRestart()) return false; FreenetURI redirect; synchronized (this) { finished = false; redirect = getFailedMessage == null ? null : getFailedMessage.redirectURI; if (persistenceType == PERSIST_FOREVER && getFailedMessage != null) getFailedMessage.removeFrom(container); this.getFailedMessage = null; if (persistenceType == PERSIST_FOREVER && allDataPending != null) allDataPending.removeFrom(container); this.allDataPending = null; if (persistenceType == PERSIST_FOREVER && postFetchProtocolErrorMessage != null) postFetchProtocolErrorMessage.removeFrom(container); this.postFetchProtocolErrorMessage = null; if (persistenceType == PERSIST_FOREVER && progressPending != null) progressPending.removeFrom(container); this.progressPending = null; started = false; } if (persistenceType == PERSIST_FOREVER) container.store(this); try { if (getter.restart(redirect, container, context)) { synchronized (this) { if (redirect != null) { if (persistenceType == PERSIST_FOREVER) uri.removeFrom(container); this.uri = redirect; } started = true; } if (persistenceType == PERSIST_FOREVER) container.store(this); } return true; } catch (FetchException e) { onFailure(e, null, container); return false; } }
public void onSuccess(FetchResult result, ClientGetter state, ObjectContainer container) { Logger.minor(this, "Succeeded: " + identifier); Bucket data = result.asBucket(); if (persistenceType == PERSIST_FOREVER) { if (data != null) container.activate(data, 5); if (returnBucket != null) container.activate(returnBucket, 5); container.activate(client, 1); if (tempFile != null) container.activate(tempFile, 5); if (targetFile != null) container.activate(targetFile, 5); } if (returnBucket != data && !binaryBlob) { boolean failed = true; synchronized (this) { if (finished) { Logger.error( this, "Already finished but onSuccess() for " + this + " data = " + data, new Exception("debug")); data.free(); if (persistenceType == PERSIST_FOREVER) data.removeFrom(container); return; // Already failed - bucket error maybe?? } if (returnType == ClientGetMessage.RETURN_TYPE_DIRECT && returnBucket == null) { // Lost bucket for some reason e.g. bucket error (caused by IOException) on previous try?? // Recover... returnBucket = data; failed = false; } } if (failed && persistenceType == PERSIST_FOREVER) { if (container.ext().getID(returnBucket) == container.ext().getID(data)) { Logger.error( this, "DB4O BUG DETECTED WITHOUT ARRAY HANDLING! EVIL HORRIBLE BUG! UID(returnBucket)=" + container.ext().getID(returnBucket) + " for " + returnBucket + " active=" + container.ext().isActive(returnBucket) + " stored = " + container.ext().isStored(returnBucket) + " but UID(data)=" + container.ext().getID(data) + " for " + data + " active = " + container.ext().isActive(data) + " stored = " + container.ext().isStored(data)); // Succeed anyway, hope that the returned bucket is consistent... returnBucket = data; failed = false; } } if (failed) { Logger.error( this, "returnBucket = " + returnBucket + " but onSuccess() data = " + data, new Exception("debug")); // Caller guarantees that data == returnBucket onFailure( new FetchException(FetchException.INTERNAL_ERROR, "Data != returnBucket"), null, container); return; } } boolean dontFree = false; // FIXME I don't think this is a problem in this case...? (Disk write while locked..) AllDataMessage adm = null; synchronized (this) { if (succeeded) { Logger.error(this, "onSuccess called twice for " + this + " (" + identifier + ')'); return; // We might be called twice; ignore it if so. } started = true; if (!binaryBlob) this.foundDataMimeType = result.getMimeType(); else this.foundDataMimeType = BinaryBlob.MIME_TYPE; if (returnType == ClientGetMessage.RETURN_TYPE_DIRECT) { // Send all the data at once // FIXME there should be other options // FIXME: CompletionTime is set on finish() : we need to give it current time here // but it means we won't always return the same value to clients... Does it matter ? adm = new AllDataMessage( returnBucket, identifier, global, startupTime, System.currentTimeMillis(), this.foundDataMimeType); if (persistenceType == PERSIST_CONNECTION) adm.setFreeOnSent(); dontFree = true; /* * } else if(returnType == ClientGetMessage.RETURN_TYPE_NONE) { // Do nothing */ } else if (returnType == ClientGetMessage.RETURN_TYPE_DISK) { // Write to temp file, then rename over filename if (!FileUtil.renameTo(tempFile, targetFile)) { postFetchProtocolErrorMessage = new ProtocolErrorMessage( ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, null, identifier, global); // Don't delete temp file, user might want it. } returnBucket = new FileBucket(targetFile, false, true, false, false, false); } if (persistenceType == PERSIST_FOREVER && progressPending != null) { container.activate(progressPending, 1); progressPending.removeFrom(container); } progressPending = null; this.foundDataLength = returnBucket.size(); this.succeeded = true; finished = true; } trySendDataFoundOrGetFailed(null, container); if (adm != null) trySendAllDataMessage(adm, null, container); if (!dontFree) { data.free(); } if (persistenceType == PERSIST_FOREVER) { returnBucket.storeTo(container); container.store(this); } finish(container); if (client != null) client.notifySuccess(this, container); }