Author: toad
Date: 2007-02-16 20:59:34 +0000 (Fri, 16 Feb 2007)
New Revision: 11823
Modified:
trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
trunk/freenet/src/freenet/client/async/USKChecker.java
trunk/freenet/src/freenet/node/SendableGet.java
trunk/freenet/src/freenet/node/SendableRequest.java
trunk/freenet/src/freenet/node/SimpleSendableInsert.java
Log:
Infrastructure for multiple requests per registered SendableGet.
Modified: trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
2007-02-16 20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
2007-02-16 20:59:34 UTC (rev 11823)
@@ -5,6 +5,7 @@
import freenet.client.FetchContext;
import freenet.keys.ClientKey;
+import freenet.keys.ClientSSK;
import freenet.node.SendableGet;
import freenet.support.Logger;
@@ -15,6 +16,7 @@
final int maxRetries;
private int retryCount;
final FetchContext ctx;
+ static final int[] keys = new int[] { 0 };
BaseSingleFileFetcher(ClientKey key, int maxRetries, FetchContext ctx,
ClientRequester parent) {
super(parent);
@@ -23,8 +25,16 @@
this.key = key;
this.ctx = ctx;
}
+
+ public int[] allKeys() {
+ return keys;
+ }
- public ClientKey getKey() {
+ public int chooseKey() {
+ return 0;
+ }
+
+ public ClientKey getKey(int token) {
return key;
}
@@ -32,6 +42,10 @@
return ctx;
}
+ public boolean isSSK() {
+ return key instanceof ClientSSK;
+ }
+
/** Try again - returns true if we can retry */
protected boolean retry() {
retryCount++;
Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
2007-02-16 20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
2007-02-16 20:59:34 UTC (rev 11823)
@@ -168,22 +168,26 @@
if(req instanceof SendableGet) {
SendableGet getter = (SendableGet)req;
if(!getter.ignoreStore()) {
- ClientKeyBlock block;
- try {
- block = node.fetchKey(getter.getKey(),
getter.dontCache());
- } catch (KeyVerifyException e) {
- // Verify exception, probably bogus at
source;
- // verifies at low-level, but not at
decode.
- if(logMINOR)
- Logger.minor(this, "Decode
failed: "+e, e);
- getter.onFailure(new
LowLevelGetException(LowLevelGetException.DECODE_FAILED));
- return;
+ int[] keyTokens = getter.allKeys();
+ for(int i=0;i<keyTokens.length;i++) {
+ int tok = keyTokens[i];
+ ClientKeyBlock block;
+ try {
+ block =
node.fetchKey(getter.getKey(tok), getter.dontCache());
+ } catch (KeyVerifyException e) {
+ // Verify exception, probably
bogus at source;
+ // verifies at low-level, but
not at decode.
+ if(logMINOR)
+ Logger.minor(this,
"Decode failed: "+e, e);
+ getter.onFailure(new
LowLevelGetException(LowLevelGetException.DECODE_FAILED), tok);
+ return;
+ }
+ if(block != null) {
+ if(logMINOR) Logger.minor(this,
"Can fulfill "+req+" immediately from store");
+ getter.onSuccess(block, true,
tok);
+ return;
+ }
}
- if(block != null) {
- if(logMINOR) Logger.minor(this, "Can
fulfill "+req+" immediately from store");
- getter.onSuccess(block, true);
- return;
- }
}
}
innerRegister(req);
Modified: trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
2007-02-16 20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
2007-02-16 20:59:34 UTC (rev 11823)
@@ -6,9 +6,9 @@
import java.io.IOException;
import freenet.client.ClientMetadata;
+import freenet.client.FetchContext;
import freenet.client.FetchException;
import freenet.client.FetchResult;
-import freenet.client.FetchContext;
import freenet.keys.ClientKey;
import freenet.keys.ClientKeyBlock;
import freenet.keys.KeyDecodeException;
@@ -36,7 +36,7 @@
final long token;
// Translate it, then call the real onFailure
- public void onFailure(LowLevelGetException e) {
+ public void onFailure(LowLevelGetException e, int reqTokenIgnored) {
switch(e.code) {
case LowLevelGetException.DATA_NOT_FOUND:
onFailure(new
FetchException(FetchException.DATA_NOT_FOUND));
@@ -105,7 +105,7 @@
rcb.onSuccess(data, this);
}
- public void onSuccess(ClientKeyBlock block, boolean fromStore) {
+ public void onSuccess(ClientKeyBlock block, boolean fromStore, int
reqTokenIgnored) {
Bucket data = extract(block);
if(data == null) return; // failed
if(!block.isMetadata()) {
Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2007-02-16 20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2007-02-16 20:59:34 UTC (rev 11823)
@@ -283,21 +283,24 @@
return finished;
}
- public void send(NodeClientCore core) {
+ public boolean send(NodeClientCore core) {
try {
if(logMINOR) Logger.minor(this, "Starting request:
"+this);
ClientKeyBlock b = getBlock();
if(b != null)
core.realPut(b, ctx.cacheLocalRequests);
- else
+ else {
fail(new
InserterException(InserterException.CANCELLED));
+ return false;
+ }
} catch (LowLevelPutException e) {
onFailure(e);
if(logMINOR) Logger.minor(this, "Request failed:
"+this+" for "+e);
- return;
+ return true;
}
if(logMINOR) Logger.minor(this, "Request succeeded: "+this);
onSuccess();
+ return true;
}
public Object getClient() {
Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2007-02-16 20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2007-02-16 20:59:34 UTC (rev 11823)
@@ -113,7 +113,7 @@
// Process the completed data. May result in us going to a
// splitfile, or another SingleFileFetcher, etc.
- public void onSuccess(ClientKeyBlock block, boolean fromStore) {
+ public void onSuccess(ClientKeyBlock block, boolean fromStore, int
token) {
parent.completedBlock(fromStore);
// Extract data
Bucket data = extract(block);
Modified: trunk/freenet/src/freenet/client/async/USKChecker.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKChecker.java 2007-02-16
20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/client/async/USKChecker.java 2007-02-16
20:59:34 UTC (rev 11823)
@@ -25,11 +25,11 @@
this.cb = cb;
}
- public void onSuccess(ClientKeyBlock block, boolean fromStore) {
+ public void onSuccess(ClientKeyBlock block, boolean fromStore, int
token) {
cb.onSuccess((ClientSSKBlock)block);
}
- public void onFailure(LowLevelGetException e) {
+ public void onFailure(LowLevelGetException e, int token) {
if(Logger.shouldLog(Logger.MINOR, this))
Logger.minor(this, "onFailure: "+e+" for "+this);
// Firstly, can we retry?
Modified: trunk/freenet/src/freenet/node/SendableGet.java
===================================================================
--- trunk/freenet/src/freenet/node/SendableGet.java 2007-02-16 20:26:10 UTC
(rev 11822)
+++ trunk/freenet/src/freenet/node/SendableGet.java 2007-02-16 20:59:34 UTC
(rev 11823)
@@ -5,10 +5,8 @@
import freenet.client.FetchContext;
import freenet.client.async.ClientRequester;
-import freenet.keys.ClientCHK;
import freenet.keys.ClientKey;
import freenet.keys.ClientKeyBlock;
-import freenet.keys.ClientSSK;
import freenet.support.Logger;
/**
@@ -16,20 +14,30 @@
*/
public abstract class SendableGet implements SendableRequest {
+ /** Is this an SSK? */
+ public abstract boolean isSSK();
+
/** Parent BaseClientGetter. Required for schedulers. */
public final ClientRequester parent;
- /** Get the key to fetch (this time!). */
- public abstract ClientKey getKey();
+ /** Choose a key to fetch.
+ * @return An integer identifying a specific key. -1 indicates no keys
available. */
+ public abstract int chooseKey();
+ /** All key identifiers */
+ public abstract int[] allKeys();
+
+ /** Get a numbered key to fetch. */
+ public abstract ClientKey getKey(int token);
+
/** Get the fetch context (settings) object. */
public abstract FetchContext getContext();
/** Called when/if the low-level request succeeds. */
- public abstract void onSuccess(ClientKeyBlock block, boolean fromStore);
+ public abstract void onSuccess(ClientKeyBlock block, boolean fromStore,
int token);
/** Called when/if the low-level request fails. */
- public abstract void onFailure(LowLevelGetException e);
+ public abstract void onFailure(LowLevelGetException e, int token);
/** Should the request ignore the datastore? */
public abstract boolean ignoreStore();
@@ -43,40 +51,46 @@
this.parent = parent;
}
- /** Do the request, blocking. Called by RequestStarter. */
- public void send(NodeClientCore core) {
- synchronized (this) {
- if(isCancelled()) {
- onFailure(new
LowLevelGetException(LowLevelGetException.CANCELLED));
- return;
- }
+ /** Do the request, blocking. Called by RequestStarter.
+ * @return True if a request was executed. False if caller should try
to find another request, and remove
+ * this one from the queue. */
+ public boolean send(NodeClientCore core) {
+ FetchContext ctx = getContext();
+ while(true) {
+ synchronized (this) {
+ if(isCancelled()) {
+ onFailure(new
LowLevelGetException(LowLevelGetException.CANCELLED), -1);
+ return false;
+ }
+ }
+ ClientKeyBlock block;
+ int keyNum = -1;
+ try {
+ keyNum = chooseKey();
+ if(keyNum == -1) return false;
+ ClientKey key = getKey(keyNum);
+ if(key == null) continue;
+ block = core.realGetKey(key,
ctx.localRequestOnly, ctx.cacheLocalRequests, ctx.ignoreStore);
+ } catch (LowLevelGetException e) {
+ onFailure(e, keyNum);
+ return true;
+ } catch (Throwable t) {
+ Logger.error(this, "Caught "+t, t);
+ onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum);
+ return true;
+ }
+ onSuccess(block, false, keyNum);
+ return true;
}
- // Do we need to support the last 3?
- ClientKeyBlock block;
- try {
- FetchContext ctx = getContext();
- block = core.realGetKey(getKey(), ctx.localRequestOnly,
ctx.cacheLocalRequests, ctx.ignoreStore);
- } catch (LowLevelGetException e) {
- onFailure(e);
- return;
- } catch (Throwable t) {
- Logger.error(this, "Caught "+t, t);
- onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR));
- return;
- }
- onSuccess(block, false);
}
public void schedule() {
- ClientKey key = getKey();
if(Logger.shouldLog(Logger.MINOR, this))
- Logger.minor(this, "Scheduling "+this+" for "+key);
- if(key instanceof ClientCHK)
- parent.chkScheduler.register(this);
- else if(key instanceof ClientSSK)
+ Logger.minor(this, "Scheduling "+this);
+ if(isSSK())
parent.sskScheduler.register(this);
else
- throw new IllegalStateException(String.valueOf(key));
+ parent.chkScheduler.register(this);
}
}
Modified: trunk/freenet/src/freenet/node/SendableRequest.java
===================================================================
--- trunk/freenet/src/freenet/node/SendableRequest.java 2007-02-16 20:26:10 UTC
(rev 11822)
+++ trunk/freenet/src/freenet/node/SendableRequest.java 2007-02-16 20:59:34 UTC
(rev 11823)
@@ -15,8 +15,10 @@
public int getRetryCount();
/** ONLY called by RequestStarter. Start the actual request using the
NodeClientCore
- * provided. The request has been removed from the structure already. */
- public void send(NodeClientCore node);
+ * provided. The request has been removed from the structure already,
if canRemove().
+ * @return True if a request was sent, false otherwise (in which case
the request will
+ * be removed if it hasn't already been). */
+ public boolean send(NodeClientCore node);
/** Get client context object */
public Object getClient();
Modified: trunk/freenet/src/freenet/node/SimpleSendableInsert.java
===================================================================
--- trunk/freenet/src/freenet/node/SimpleSendableInsert.java 2007-02-16
20:26:10 UTC (rev 11822)
+++ trunk/freenet/src/freenet/node/SimpleSendableInsert.java 2007-02-16
20:59:34 UTC (rev 11823)
@@ -45,7 +45,7 @@
return 0;
}
- public void send(NodeClientCore core) {
+ public boolean send(NodeClientCore core) {
boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
try {
if(logMINOR) Logger.minor(this, "Starting request:
"+this);
@@ -53,12 +53,13 @@
} catch (LowLevelPutException e) {
onFailure(e);
if(logMINOR) Logger.minor(this, "Request failed:
"+this+" for "+e);
- return;
+ return true;
} finally {
finished = true;
}
if(logMINOR) Logger.minor(this, "Request succeeded: "+this);
onSuccess();
+ return true;
}
public Object getClient() {