Author: toad
Date: 2008-06-17 22:17:59 +0000 (Tue, 17 Jun 2008)
New Revision: 20419

Added:
   branches/db4o/freenet/src/freenet/client/async/USKFetcherTag.java
   branches/db4o/freenet/src/freenet/client/async/USKManagerPersistent.java
Modified:
   branches/db4o/freenet/src/freenet/client/async/ClientContext.java
   branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java
   branches/db4o/freenet/src/freenet/client/async/USKCallback.java
   branches/db4o/freenet/src/freenet/client/async/USKInserter.java
   branches/db4o/freenet/src/freenet/client/async/USKManager.java
   branches/db4o/freenet/src/freenet/node/NodeClientCore.java
Log:
Add USKFetcherTag. This is the only part of the USK mechanism that can be 
persisted. They are restarted on startup.
Use USKFetcherTag's and not USKFetcher's.
USKFetcher's are only used internally.

Modified: branches/db4o/freenet/src/freenet/client/async/ClientContext.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientContext.java   
2008-06-17 19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/client/async/ClientContext.java   
2008-06-17 22:17:59 UTC (rev 20419)
@@ -35,6 +35,7 @@
        public final ArchiveManager archiveManager;
        public final BucketFactory persistentBucketFactory;
        public final HealingQueue healingQueue;
+       public final USKManager uskManager;

        public ClientContext(NodeClientCore core) {
                this.fecQueue = core.fecQueue;
@@ -50,6 +51,7 @@
                archiveManager = core.archiveManager;
                this.persistentBucketFactory = 
core.persistentEncryptedTempBucketFactory;
                this.healingQueue = core.getHealingQueue();
+               this.uskManager = core.uskManager;
        }

        public void start(final ClientPutter inserter, final boolean 
earlyEncode) throws InsertException {

Modified: branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java       
2008-06-17 19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java       
2008-06-17 22:17:59 UTC (rev 20419)
@@ -758,12 +758,12 @@
                        }
                } else {
                        // Do a thorough, blocking search
-                       USKFetcher fetcher =
-                               
ctx.uskManager.getFetcher(usk.copy(-usk.suggestedEdition), ctx, requester, 
false);
+                       USKFetcherTag tag = 
+                               
ctx.uskManager.getFetcher(usk.copy(-usk.suggestedEdition), ctx, false, 
requester.persistent(),
+                                               new 
MyUSKFetcherCallback(requester, cb, clientMetadata, usk, metaStrings, ctx, 
actx, maxRetries, recursionLevel, dontTellClientGet, l, returnBucket), 
container, context);
                        if(isEssential)
                                requester.addMustSucceedBlocks(1);
-                       fetcher.addCallback(new MyUSKFetcherCallback(requester, 
cb, clientMetadata, usk, metaStrings, ctx, actx, maxRetries, recursionLevel, 
dontTellClientGet, l, returnBucket));
-                       return fetcher;
+                       return tag;
                }
        }

@@ -797,7 +797,7 @@
                        this.returnBucket = returnBucket;
                }

-               public void onFoundEdition(long l, USK newUSK, ObjectContainer 
container, ClientContext context) {
+               public void onFoundEdition(long l, USK newUSK, ObjectContainer 
container, ClientContext context, boolean metadata, short codec, byte[] data) {
                        ClientSSK key = usk.getSSK(l);
                        try {
                                if(l == usk.suggestedEdition) {

Modified: branches/db4o/freenet/src/freenet/client/async/USKCallback.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/USKCallback.java     
2008-06-17 19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/client/async/USKCallback.java     
2008-06-17 22:17:59 UTC (rev 20419)
@@ -16,7 +16,7 @@
        /** Found the latest edition.
         * @param l The edition number.
         * @param key The key. */
-       void onFoundEdition(long l, USK key, ObjectContainer container, 
ClientContext context);
+       void onFoundEdition(long l, USK key, ObjectContainer container, 
ClientContext context, boolean metadata, short codec, byte[] data);

        /**
         * Priority at which the polling should run normally.

Added: branches/db4o/freenet/src/freenet/client/async/USKFetcherTag.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/USKFetcherTag.java           
                (rev 0)
+++ branches/db4o/freenet/src/freenet/client/async/USKFetcherTag.java   
2008-06-17 22:17:59 UTC (rev 20419)
@@ -0,0 +1,114 @@
+package freenet.client.async;
+
+import com.db4o.ObjectContainer;
+
+import freenet.client.FetchContext;
+import freenet.keys.USK;
+import freenet.node.RequestClient;
+
+/**
+ * Not the actual fetcher. Just a tag associating a USK with the client that 
should be called when
+ * the fetch has been done. Can be included in persistent requests. On 
startup, all USK fetches are
+ * restarted, but this remains the same: the actual USKFetcher's are always 
transient.
+ * @author toad
+ */
+class USKFetcherTag implements ClientGetState, USKFetcherCallback {
+
+       /** For persistence */
+       public final long nodeDBHandle;
+       /** The callback */
+       public final USKFetcherCallback callback;
+       /** The original USK */
+       public final USK origUSK;
+       /** The edition number found so far */
+       protected long edition;
+       /** Persistent?? */
+       public final boolean persistent;
+       /** Context */
+       public final FetchContext ctx;
+       public final boolean keepLastData;
+       /** Priority */
+       private short priority;
+       private long token;
+       transient USKFetcher fetcher;
+       
+       private USKFetcherTag(USK origUSK, USKFetcherCallback callback, long 
nodeDBHandle, boolean persistent, ObjectContainer container, FetchContext ctx, 
boolean keepLastData, long token) {
+               this.nodeDBHandle = nodeDBHandle;
+               this.callback = callback;
+               this.origUSK = origUSK;
+               this.edition = origUSK.suggestedEdition;
+               this.persistent = persistent;
+               this.ctx = ctx;
+               this.keepLastData = keepLastData;
+               this.token = token;
+       }
+       
+       public static USKFetcherTag create(USK usk, USKFetcherCallback 
callback, long nodeDBHandle, boolean persistent, 
+                       ObjectContainer container, FetchContext ctx, boolean 
keepLast, int token) {
+               USKFetcherTag tag = new USKFetcherTag(usk, callback, 
nodeDBHandle, persistent, container, ctx, keepLast, token);
+               if(persistent) container.set(tag);
+               return tag;
+       }
+       
+       synchronized void updatedEdition(long ed, ObjectContainer container) {
+               if(edition < ed) edition = ed;
+               if(persistent) container.set(this); // Update
+       }
+
+       private static final RequestClient client = new RequestClient() {
+
+               public boolean persistent() {
+                       // The actual USK fetch is non-persistent, only the 
tags survive a restart.
+                       return false;
+               }
+               
+       };
+       
+       public void start(USKManager manager, ObjectContainer container, 
ClientContext context) {
+               USK usk = origUSK;
+               if(usk.suggestedEdition < edition)
+                       usk = usk.copy(edition);
+               fetcher = manager.getFetcher(usk, ctx, new 
USKFetcherWrapper(usk, priority, client), keepLastData);
+               fetcher.addCallback(this);
+               fetcher.schedule(container, context);
+       }
+
+       public void cancel(ObjectContainer container, ClientContext context) {
+               if(fetcher != null) fetcher.cancel(container, context);
+       }
+
+       public long getToken() {
+               return token;
+       }
+
+       public void schedule(ObjectContainer container, ClientContext context) {
+               start(context.uskManager, container, context);
+       }
+
+       public void onCancelled(ObjectContainer container, ClientContext 
context) {
+               callback.onCancelled(container, context);
+               if(persistent)
+                       container.delete(this);
+       }
+
+       public void onFailure(ObjectContainer container, ClientContext context) 
{
+               callback.onFailure(container, context);
+               if(persistent)
+                       container.delete(this);
+       }
+
+       public short getPollingPriorityNormal() {
+               return callback.getPollingPriorityNormal();
+       }
+
+       public short getPollingPriorityProgress() {
+               return callback.getPollingPriorityProgress();
+       }
+
+       public void onFoundEdition(long l, USK key, ObjectContainer container, 
ClientContext context, boolean metadata, short codec, byte[] data) {
+               callback.onFoundEdition(l, key, container, context, metadata, 
codec, data);
+               if(persistent)
+                       container.delete(this);
+       }
+
+}

Modified: branches/db4o/freenet/src/freenet/client/async/USKInserter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/USKInserter.java     
2008-06-17 19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/client/async/USKInserter.java     
2008-06-17 22:17:59 UTC (rev 20419)
@@ -43,7 +43,7 @@
        final InsertableUSK privUSK;
        final USK pubUSK;
        /** Scanning for latest slot */
-       private USKFetcher fetcher;
+       private USKFetcherTag fetcher;
        /** Insert the actual SSK */
        private SingleBlockInserter sbi;
        private long edition;
@@ -53,7 +53,7 @@
        /** After attempting inserts on this many slots, go back to the Fetcher 
*/
        private static final long MAX_TRIED_SLOTS = 10;

-       public void schedule(ObjectContainer container) throws InsertException {
+       public void schedule(ObjectContainer container, ClientContext context) 
throws InsertException {
                // Caller calls schedule()
                // schedule() calls scheduleFetcher()
                // scheduleFetcher() creates a Fetcher (set up to tell us about 
author-errors as well as valid inserts)
@@ -63,7 +63,7 @@
                // if that succeeds, we complete
                // if that fails, we increment our index and try again (in the 
callback)
                // if that continues to fail 5 times, we go back to 
scheduleFetcher()
-               scheduleFetcher();
+               scheduleFetcher(container, context);
        }

        /**
@@ -71,27 +71,25 @@
         * The Fetcher must be insert-mode, in other words, it must know that 
we want the latest edition,
         * including author errors and so on.
         */
-       private void scheduleFetcher() {
+       private void scheduleFetcher(ObjectContainer container, ClientContext 
context) {
                synchronized(this) {
                        if(Logger.shouldLog(Logger.MINOR, this))
                                Logger.minor(this, "scheduling fetcher for 
"+pubUSK.getURI());
                        if(finished) return;
-                       fetcher = 
ctx.uskManager.getFetcherForInsertDontSchedule(pubUSK, parent.priorityClass, 
this, parent.getClient());
+                       fetcher = 
ctx.uskManager.getFetcherForInsertDontSchedule(pubUSK, parent.priorityClass, 
this, parent.getClient(), container, context);
                }
-               fetcher.schedule();
+               fetcher.schedule(container, context);
        }

-       public void onFoundEdition(long l, USK key, ObjectContainer container) {
+       public void onFoundEdition(long l, USK key, ObjectContainer container, 
ClientContext context, boolean lastContentWasMetadata, short codec, byte[] 
hisData) {
                boolean alreadyInserted = false;
                synchronized(this) {
                        edition = Math.max(l, edition);
                        consecutiveCollisions = 0;
-                       if((fetcher.lastContentWasMetadata() == isMetadata) && 
fetcher.hasLastData()
-                                       && (fetcher.lastCompressionCodec() == 
compressionCodec)) {
+                       if((lastContentWasMetadata == isMetadata) && hisData != 
null
+                                       && (codec == compressionCodec)) {
                                try {
                                        byte[] myData = 
BucketTools.toByteArray(data);
-                                       byte[] hisData = 
BucketTools.toByteArray(fetcher.getLastData());
-                                       fetcher.freeLastData();
                                        if(Arrays.equals(myData, hisData)) {
                                                // Success
                                                alreadyInserted = true;
@@ -108,10 +106,10 @@
                }
                if(alreadyInserted) {
                        // Success!
-                       cb.onEncode(pubUSK.copy(edition), this);
+                       cb.onEncode(pubUSK.copy(edition), this, container, 
context);
                        parent.addMustSucceedBlocks(1);
                        parent.completedBlock(true);
-                       cb.onSuccess(this);
+                       cb.onSuccess(this, container, context);
                } else {
                        scheduleInsert(container);
                }

Modified: branches/db4o/freenet/src/freenet/client/async/USKManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/USKManager.java      
2008-06-17 19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/client/async/USKManager.java      
2008-06-17 22:17:59 UTC (rev 20419)
@@ -6,7 +6,10 @@
 import java.util.HashMap;
 import java.util.Vector;

+import com.db4o.ObjectContainer;
+
 import freenet.client.FetchContext;
+import freenet.client.async.SingleFileFetcher.MyUSKFetcherCallback;
 import freenet.keys.USK;
 import freenet.node.NodeClientCore;
 import freenet.node.RequestClient;
@@ -42,7 +45,6 @@
        final FetchContext backgroundFetchContext;

        final Ticker ticker;
-

        public USKManager(NodeClientCore core) {
                backgroundFetchContext = 
core.makeClient(RequestStarter.UPDATE_PRIORITY_CLASS).getFetchContext();
@@ -68,7 +70,12 @@
                else return -1;
        }

-       public synchronized USKFetcher getFetcher(USK usk, FetchContext ctx,
+       public USKFetcherTag getFetcher(USK usk, FetchContext ctx, boolean 
keepLast, boolean persistent, 
+                       USKFetcherCallback callback, ObjectContainer container, 
ClientContext context) {
+               return USKFetcherTag.create(usk, callback, 
context.nodeDBHandle, persistent, container, ctx, keepLast, 0);
+       }
+
+       synchronized USKFetcher getFetcher(USK usk, FetchContext ctx,
                        ClientRequester requester, boolean keepLastData) {
                USKFetcher f = (USKFetcher) fetchersByUSK.get(usk);
                USK clear = usk.clearCopy();
@@ -82,12 +89,9 @@
                fetchersByUSK.put(usk, f);
                return f;
        }
-
-       public USKFetcher getFetcherForInsertDontSchedule(USK usk, short 
prioClass, USKFetcherCallback cb, RequestClient client) {
-               USKFetcher f = new USKFetcher(usk, this, 
backgroundFetchContext, 
-                               new USKFetcherWrapper(usk, prioClass, client), 
3, false, true);
-               f.addCallback(cb);
-               return f;
+       
+       public USKFetcherTag getFetcherForInsertDontSchedule(USK usk, short 
prioClass, USKFetcherCallback cb, RequestClient client, ObjectContainer 
container, ClientContext context) {
+               return getFetcher(usk, backgroundFetchContext, true, 
client.persistent(), cb, container, context);
        }

        public void startTemporaryBackgroundFetcher(USK usk) {

Added: branches/db4o/freenet/src/freenet/client/async/USKManagerPersistent.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/USKManagerPersistent.java    
                        (rev 0)
+++ branches/db4o/freenet/src/freenet/client/async/USKManagerPersistent.java    
2008-06-17 22:17:59 UTC (rev 20419)
@@ -0,0 +1,26 @@
+package freenet.client.async;
+
+import com.db4o.ObjectContainer;
+import com.db4o.ObjectSet;
+import com.db4o.query.Predicate;
+
+/**
+ * The persistent part of a USKManager.
+ * @author toad
+ *
+ */
+public class USKManagerPersistent {
+       
+       public static void init(USKManager manager, ObjectContainer container, 
final ClientContext context) {
+               ObjectSet set = container.query(new Predicate() {
+                       public boolean match(USKFetcherTag tag) {
+                               return tag.nodeDBHandle == context.nodeDBHandle;
+                       }
+               });
+               while(set.hasNext()) {
+                       USKFetcherTag tag = (USKFetcherTag) set.next();
+                       tag.start(manager, container, context);
+               }
+       }
+
+}

Modified: branches/db4o/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeClientCore.java  2008-06-17 
19:07:05 UTC (rev 20418)
+++ branches/db4o/freenet/src/freenet/node/NodeClientCore.java  2008-06-17 
22:17:59 UTC (rev 20419)
@@ -19,6 +19,7 @@
 import freenet.client.async.HealingQueue;
 import freenet.client.async.SimpleHealingQueue;
 import freenet.client.async.USKManager;
+import freenet.client.async.USKManagerPersistent;
 import freenet.client.events.SimpleEventProducer;
 import freenet.clients.http.FProxyToadlet;
 import freenet.clients.http.SimpleToadletServer;
@@ -296,6 +297,7 @@
                Logger.normal(this, "Initializing USK Manager");
                System.out.println("Initializing USK Manager");
                uskManager = new USKManager(this);
+               USKManagerPersistent.init(uskManager, container, clientContext);

                healingQueue = new 
SimpleHealingQueue(requestStarters.chkPutScheduler,
                                new InsertContext(tempBucketFactory, 
tempBucketFactory, persistentTempBucketFactory, 


Reply via email to