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);
+
+}


Reply via email to