Author: toad
Date: 2006-08-31 17:45:44 +0000 (Thu, 31 Aug 2006)
New Revision: 10306
Added:
trunk/freenet/src/freenet/client/async/USKRetriever.java
trunk/freenet/src/freenet/client/async/USKRetrieverCallback.java
Modified:
trunk/freenet/src/freenet/client/async/ClientGetState.java
trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
trunk/freenet/src/freenet/client/async/USKFetcher.java
trunk/freenet/src/freenet/client/async/USKManager.java
Log:
Add USKRetriever: A client can subscribe to a USK, and have the data
automatically fetched when updates are found, and returned to it.
Will be used for ARK fetches, and later by FCP.
Modified: trunk/freenet/src/freenet/client/async/ClientGetState.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetState.java 2006-08-31
15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/ClientGetState.java 2006-08-31
17:45:44 UTC (rev 10306)
@@ -10,4 +10,5 @@
public void cancel();
+ public Object getToken();
}
Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2006-08-31 15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2006-08-31 17:45:44 UTC (rev 10306)
@@ -54,7 +54,7 @@
* @param token
* @param dontTellClientGet
*/
- public SingleFileFetcher(ClientGetter get, GetCompletionCallback cb,
ClientMetadata metadata,
+ public SingleFileFetcher(ClientRequester get, GetCompletionCallback cb,
ClientMetadata metadata,
ClientKey key, LinkedList metaStrings, FetcherContext
ctx,
ArchiveContext actx, int maxRetries, int
recursionLevel,
boolean dontTellClientGet, Object token, boolean
isEssential,
@@ -353,7 +353,7 @@
}
SplitFileFetcher sf = new
SplitFileFetcher(metadata, rcb, (ClientGetter)parent, ctx,
- decompressors, clientMetadata,
actx, recursionLevel, returnBucket, false);
+ decompressors, clientMetadata,
actx, recursionLevel, returnBucket, false, token);
sf.schedule();
rcb.onBlockSetFinished(this);
// SplitFile will now run.
@@ -544,7 +544,7 @@
return (ClientGetter) parent;
}
- public static ClientGetState create(ClientGetter parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, FreenetURI uri,
FetcherContext ctx, ArchiveContext actx, int maxRetries, int recursionLevel,
boolean dontTellClientGet, Object token, boolean isEssential, Bucket
returnBucket) throws MalformedURLException, FetchException {
+ public static ClientGetState create(ClientRequester parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, FreenetURI uri,
FetcherContext ctx, ArchiveContext actx, int maxRetries, int recursionLevel,
boolean dontTellClientGet, Object token, boolean isEssential, Bucket
returnBucket) throws MalformedURLException, FetchException {
BaseClientKey key = BaseClientKey.getBaseKey(uri);
if(key instanceof ClientKey)
return new SingleFileFetcher(parent, cb,
clientMetadata, (ClientKey)key, uri.listMetaStrings(), ctx, actx, maxRetries,
recursionLevel, dontTellClientGet, token, isEssential, returnBucket);
@@ -553,7 +553,7 @@
}
}
- private static ClientGetState uskCreate(ClientGetter parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, USK usk, LinkedList
metaStrings, FetcherContext ctx, ArchiveContext actx, int maxRetries, int
recursionLevel, boolean dontTellClientGet, Object token, boolean isEssential,
Bucket returnBucket) throws FetchException {
+ private static ClientGetState uskCreate(ClientRequester parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, USK usk, LinkedList
metaStrings, FetcherContext ctx, ArchiveContext actx, int maxRetries, int
recursionLevel, boolean dontTellClientGet, Object token, boolean isEssential,
Bucket returnBucket) throws FetchException {
if(usk.suggestedEdition >= 0) {
// Return the latest known version but at least
suggestedEdition.
long edition = ctx.uskManager.lookup(usk);
@@ -586,7 +586,7 @@
public static class MyUSKFetcherCallback implements USKFetcherCallback {
- final ClientGetter parent;
+ final ClientRequester parent;
final GetCompletionCallback cb;
final ClientMetadata clientMetadata;
final USK usk;
@@ -599,7 +599,7 @@
final Object token;
final Bucket returnBucket;
- public MyUSKFetcherCallback(ClientGetter parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, USK usk, LinkedList
metaStrings, FetcherContext ctx, ArchiveContext actx, int maxRetries, int
recursionLevel, boolean dontTellClientGet, Object token, Bucket returnBucket) {
+ public MyUSKFetcherCallback(ClientRequester parent,
GetCompletionCallback cb, ClientMetadata clientMetadata, USK usk, LinkedList
metaStrings, FetcherContext ctx, ArchiveContext actx, int maxRetries, int
recursionLevel, boolean dontTellClientGet, Object token, Bucket returnBucket) {
this.parent = parent;
this.cb = cb;
this.clientMetadata = clientMetadata;
Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
2006-08-31 15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
2006-08-31 17:45:44 UTC (rev 10306)
@@ -57,10 +57,11 @@
/** Preferred bucket to return data in */
private final Bucket returnBucket;
private boolean finished;
+ private Object token;
public SplitFileFetcher(Metadata metadata, GetCompletionCallback rcb,
ClientGetter parent,
FetcherContext newCtx, LinkedList decompressors,
ClientMetadata clientMetadata,
- ArchiveContext actx, int recursionLevel, Bucket
returnBucket, boolean dontTellParent) throws FetchException,
MetadataParseException {
+ ArchiveContext actx, int recursionLevel, Bucket
returnBucket, boolean dontTellParent, Object token) throws FetchException,
MetadataParseException {
this.finished = false;
this.returnBucket = returnBucket;
this.fetchContext = newCtx;
@@ -129,6 +130,7 @@
segments[i] = new
SplitFileFetcherSegment(splitfileType, dataBlocks, checkBlocks, this,
archiveContext, fetchContext, maxTempLength, splitUseLengths, recursionLevel+1);
}
}
+ this.token = token;
}
/** Return the final status of the fetch. Throws an exception, or
returns a
@@ -254,4 +256,8 @@
segments[i].cancel();
}
+ public Object getToken() {
+ return token;
+ }
+
}
Modified: trunk/freenet/src/freenet/client/async/USKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKFetcher.java 2006-08-31
15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/USKFetcher.java 2006-08-31
17:45:44 UTC (rev 10306)
@@ -195,12 +195,14 @@
private boolean started;
- USKFetcher(USK origUSK, USKManager manager, FetcherContext ctx,
ClientRequester parent, int minFailures, boolean pollForever, boolean
keepLastData) {
- this(origUSK, manager, ctx, parent, minFailures, pollForever,
DEFAULT_MAX_MIN_FAILURES, keepLastData);
+ private Object token;
+
+ USKFetcher(USK origUSK, USKManager manager, FetcherContext ctx,
ClientRequester parent, int minFailures, boolean pollForever, boolean
keepLastData, Object token) {
+ this(origUSK, manager, ctx, parent, minFailures, pollForever,
DEFAULT_MAX_MIN_FAILURES, keepLastData, token);
}
// FIXME use this!
- USKFetcher(USK origUSK, USKManager manager, FetcherContext ctx,
ClientRequester parent, int minFailures, boolean pollForever, long
maxProbeEditions, boolean keepLastData) {
+ USKFetcher(USK origUSK, USKManager manager, FetcherContext ctx,
ClientRequester parent, int minFailures, boolean pollForever, long
maxProbeEditions, boolean keepLastData, Object token) {
this.parent = parent;
this.maxMinFailures = maxProbeEditions;
this.origUSK = origUSK;
@@ -215,6 +217,7 @@
this.backgroundPoll = pollForever;
this.keepLastData = keepLastData;
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ this.token = token;
}
void onDNF(USKAttempt att) {
@@ -496,5 +499,9 @@
public synchronized void killOnLoseSubscribers() {
this.killOnLoseSubscribers = true;
}
+
+ public Object getToken() {
+ return token;
+ }
}
Modified: trunk/freenet/src/freenet/client/async/USKManager.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKManager.java 2006-08-31
15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/USKManager.java 2006-08-31
17:45:44 UTC (rev 10306)
@@ -77,7 +77,7 @@
}
public synchronized USKFetcher getFetcher(USK usk, FetcherContext ctx,
- ClientGetter parent, boolean keepLastData) {
+ ClientRequester parent, boolean keepLastData) {
USKFetcher f = (USKFetcher) fetchersByUSK.get(usk);
USK clear = usk.clearCopy();
if(temporaryBackgroundFetchersLRU.contains(clear))
@@ -86,14 +86,14 @@
if((f.parent.priorityClass == parent.priorityClass) &&
f.ctx.equals(ctx) && f.keepLastData == keepLastData)
return f;
}
- f = new USKFetcher(usk, this, ctx, parent, 3, false,
keepLastData);
+ f = new USKFetcher(usk, this, ctx, parent, 3, false,
keepLastData, null);
fetchersByUSK.put(usk, f);
return f;
}
public USKFetcher getFetcherForInsertDontSchedule(USK usk, short
prioClass, USKFetcherCallback cb) {
USKFetcher f = new USKFetcher(usk, this,
backgroundFetchContext,
- new USKFetcherWrapper(usk, prioClass,
chkRequestScheduler, sskRequestScheduler), 3, false, true);
+ new USKFetcherWrapper(usk, prioClass,
chkRequestScheduler, sskRequestScheduler), 3, false, true, null);
f.addCallback(cb);
return f;
}
@@ -104,7 +104,7 @@
synchronized(this) {
USKFetcher f = (USKFetcher)
backgroundFetchersByClearUSK.get(clear);
if(f == null) {
- f = new USKFetcher(usk, this,
backgroundFetchContext, new USKFetcherWrapper(usk,
RequestStarter.UPDATE_PRIORITY_CLASS, chkRequestScheduler,
sskRequestScheduler), 10, true, false);
+ f = new USKFetcher(usk, this,
backgroundFetchContext, new USKFetcherWrapper(usk,
RequestStarter.UPDATE_PRIORITY_CLASS, chkRequestScheduler,
sskRequestScheduler), 10, true, false, null);
sched = f;
backgroundFetchersByClearUSK.put(clear, f);
}
@@ -178,7 +178,7 @@
if(runBackgroundFetch) {
USKFetcher f = (USKFetcher)
backgroundFetchersByClearUSK.get(clear);
if(f == null) {
- f = new USKFetcher(origUSK, this,
backgroundFetchContext, new USKFetcherWrapper(origUSK,
RequestStarter.UPDATE_PRIORITY_CLASS, chkRequestScheduler,
sskRequestScheduler), 10, true, false);
+ f = new USKFetcher(origUSK, this,
backgroundFetchContext, new USKFetcherWrapper(origUSK,
RequestStarter.UPDATE_PRIORITY_CLASS, chkRequestScheduler,
sskRequestScheduler), 10, true, false, null);
sched = f;
backgroundFetchersByClearUSK.put(clear,
f);
}
@@ -220,4 +220,24 @@
}
}
}
+
+ /**
+ * Subscribe to a USK. When it is updated, the content will be fetched
(subject to the limits in fctx),
+ * and returned to the callback.
+ * @param origUSK The USK to poll.
+ * @param cb Callback, called when we have downloaded a new key.
+ * @param runBackgroundFetch If true, start a background fetcher for
the key, which will run
+ * forever until we unsubscribe.
+ * @param fctx Fetcher context for actually fetching the keys. Not used
by the USK polling.
+ * @return
+ */
+ public USKRetriever subscribeContent(USK origUSK, USKRetrieverCallback
cb, boolean runBackgroundFetch, FetcherContext fctx, short prio, Object client)
{
+ USKRetriever ret = new USKRetriever(fctx, prio,
chkRequestScheduler, sskRequestScheduler, client, cb);
+ subscribe(origUSK, ret, runBackgroundFetch);
+ return ret;
+ }
+
+ public void unsubscribeContent(USK origUSK, USKRetriever ret, boolean
runBackgroundFetch) {
+ unsubscribe(origUSK, ret, runBackgroundFetch);
+ }
}
Added: trunk/freenet/src/freenet/client/async/USKRetriever.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKRetriever.java 2006-08-31
15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/USKRetriever.java 2006-08-31
17:45:44 UTC (rev 10306)
@@ -0,0 +1,74 @@
+package freenet.client.async;
+
+import java.net.MalformedURLException;
+
+import freenet.client.ArchiveContext;
+import freenet.client.ClientMetadata;
+import freenet.client.FetchException;
+import freenet.client.FetchResult;
+import freenet.client.FetcherContext;
+import freenet.keys.FreenetURI;
+import freenet.keys.USK;
+import freenet.support.Logger;
+
+/**
+ * Poll a USK, and when a new slot is found, fetch it.
+ */
+public class USKRetriever extends ClientRequester implements USKCallback,
GetCompletionCallback {
+
+ /** Context for fetching data */
+ final FetcherContext ctx;
+ final USKRetrieverCallback cb;
+
+ public USKRetriever(FetcherContext fctx, short prio,
ClientRequestScheduler chkSched, ClientRequestScheduler sskSched, Object
client, USKRetrieverCallback cb) {
+ super(prio, chkSched, sskSched, client);
+ this.ctx = fctx;
+ this.cb = cb;
+ }
+
+ public void onFoundEdition(long l, USK key) {
+ // Create a SingleFileFetcher for the key (as an SSK).
+ // Put the edition number into its context object.
+ // Put ourself as callback.
+ // Fetch it. If it fails, ignore it, if it succeeds, return the
data with the edition # to the client.
+ FreenetURI uri = key.getSSK(l).getURI();
+ try {
+ SingleFileFetcher getter =
+ (SingleFileFetcher)
SingleFileFetcher.create(this, this, new ClientMetadata(), uri, ctx, new
ArchiveContext(ctx.maxArchiveLevels),
+ ctx.maxNonSplitfileRetries, 0,
false, key.copy(l), true, null);
+ getter.schedule();
+ } catch (MalformedURLException e) {
+ Logger.error(this, "Impossible: "+e, e);
+ } catch (FetchException e) {
+ Logger.error(this, "Could not start fetcher for "+uri+"
: "+e, e);
+ }
+ }
+
+ public void onSuccess(FetchResult result, ClientGetState state) {
+ Object token = state.getToken();
+ FreenetURI uri = (FreenetURI) token;
+ cb.onFound(uri.getSuggestedEdition(), result);
+ }
+
+ public void onFailure(FetchException e, ClientGetState state) {
+ Object token = state.getToken();
+ Logger.error(this, "Failed to fetch "+token+" - original insert
corrupt?? : "+e, e);
+ }
+
+ public void onBlockSetFinished(ClientGetState state) {
+ // Ignore
+ }
+
+ public FreenetURI getURI() {
+ return null;
+ }
+
+ public boolean isFinished() {
+ return false;
+ }
+
+ public void notifyClients() {
+ // Ignore for now
+ }
+
+}
Added: trunk/freenet/src/freenet/client/async/USKRetrieverCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKRetrieverCallback.java
2006-08-31 15:49:33 UTC (rev 10305)
+++ trunk/freenet/src/freenet/client/async/USKRetrieverCallback.java
2006-08-31 17:45:44 UTC (rev 10306)
@@ -0,0 +1,17 @@
+package freenet.client.async;
+
+import freenet.client.FetchResult;
+
+/**
+ * Interface implemented by USKRetriever clients.
+ */
+public interface USKRetrieverCallback {
+
+ /**
+ * Called when a new edition is found and downloaded.
+ * @param edition The USK edition number.
+ * @param data The retrieved data.
+ */
+ void onFound(long edition, FetchResult data);
+
+}