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,