Author: toad
Date: 2008-05-31 15:25:30 +0000 (Sat, 31 May 2008)
New Revision: 20165
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
branches/db4o/freenet/src/freenet/node/RequestScheduler.java
branches/db4o/freenet/src/freenet/node/SendableGet.java
Log:
Run onFailure() on the databaseExecutor thread.
Make sure it runs before the remove-the-job-from-running-requests logic.
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
2008-05-31 15:15:56 UTC (rev 20164)
+++ branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
2008-05-31 15:25:30 UTC (rev 20165)
@@ -190,7 +190,17 @@
// 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, this);
+ if(onDatabaseThread)
+ getter.onFailure(new
LowLevelGetException(LowLevelGetException.DECODE_FAILED), tok, this);
+ else {
+ final SendableGet g =
getter;
+ final Object token =
tok;
+
databaseExecutor.execute(new Runnable() {
+ public void
run() {
+
g.onFailure(new LowLevelGetException(LowLevelGetException.DECODE_FAILED),
token, ClientRequestScheduler.this);
+ }
+ },
NativeThread.NORM_PRIORITY, "Block decode failed");
+ }
continue; // other keys might
be valid
}
if(block != null) {
@@ -556,4 +566,18 @@
public void removeFetchingKey(Key key) {
schedCore.removeFetchingKey(key);
}
+
+ public PrioritizedSerialExecutor getDatabaseExecutor() {
+ return databaseExecutor;
+ }
+
+ public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name) {
+ databaseExecutor.execute(new Runnable() {
+ public void run() {
+ get.onFailure(e, keyNum,
ClientRequestScheduler.this);
+ selectorContainer.commit();
+ }
+ }, prio, name);
+ }
+
}
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2008-05-31 15:15:56 UTC (rev 20164)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2008-05-31 15:25:30 UTC (rev 20165)
@@ -483,7 +483,7 @@
container.commit();
}
}
- }, NativeThread.HIGH_PRIORITY, "Remove fetching key");
+ }, NativeThread.NORM_PRIORITY, "Remove fetching key");
}
}
Modified: branches/db4o/freenet/src/freenet/node/RequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/RequestScheduler.java
2008-05-31 15:15:56 UTC (rev 20164)
+++ branches/db4o/freenet/src/freenet/node/RequestScheduler.java
2008-05-31 15:25:30 UTC (rev 20165)
@@ -8,6 +8,7 @@
import freenet.client.async.ChosenRequest;
import freenet.keys.ClientKey;
import freenet.keys.Key;
+import freenet.support.PrioritizedSerialExecutor;
public interface RequestScheduler {
@@ -52,5 +53,9 @@
public KeysFetchingLocally fetchingKeys();
public void removeFetchingKey(Key key);
+
+ public PrioritizedSerialExecutor getDatabaseExecutor();
+
+ public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name);
}
Modified: branches/db4o/freenet/src/freenet/node/SendableGet.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/SendableGet.java 2008-05-31
15:15:56 UTC (rev 20164)
+++ branches/db4o/freenet/src/freenet/node/SendableGet.java 2008-05-31
15:25:30 UTC (rev 20165)
@@ -11,6 +11,7 @@
import freenet.keys.Key;
import freenet.keys.KeyBlock;
import freenet.support.Logger;
+import freenet.support.io.NativeThread;
/**
* A low-level key fetch which can be sent immediately. @see SendableRequest
@@ -56,7 +57,7 @@
/** 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, RequestScheduler sched, Object
keyNum) {
+ public boolean send(NodeClientCore core, final RequestScheduler sched,
final Object keyNum) {
ClientKey key = getKey(keyNum);
if(key == null) {
Logger.error(this, "Key is null in send(): keyNum =
"+keyNum+" for "+this);
@@ -73,25 +74,26 @@
boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
if(isCancelled()) {
if(logMINOR) Logger.minor(this, "Cancelled: "+this);
- onFailure(new
LowLevelGetException(LowLevelGetException.CANCELLED), null, sched);
+ // callbacks must initially run at HIGH_PRIORITY so
they are executed before we remove the key from the currently running list
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.CANCELLED), null,
NativeThread.HIGH_PRIORITY, "onFailure(cancelled)");
return false;
}
try {
try {
core.realGetKey(key, ctx.localRequestOnly,
ctx.cacheLocalRequests, ctx.ignoreStore);
- } catch (LowLevelGetException e) {
- onFailure(e, keyNum, sched);
+ } catch (final LowLevelGetException e) {
+ sched.callFailure(this, e, keyNum,
NativeThread.HIGH_PRIORITY, "onFailure");
return true;
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
- onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum, sched);
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)");
return true;
}
// Don't call onSuccess(), it will be called for us by
backdoor coalescing.
sched.succeeded(this);
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
- onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum, sched);
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)");
return true;
}
return true;
@@ -141,8 +143,13 @@
getScheduler().removePendingKey(this, false, key);
}
- public void internalError(Object keyNum, Throwable t, RequestScheduler
sched) {
- onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR, t.getMessage(), t),
keyNum, sched);
+ public void internalError(final Object keyNum, final Throwable t, final
RequestScheduler sched) {
+ sched.getDatabaseExecutor().execute(new Runnable() {
+ public void run() {
+ onFailure(new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR, t.getMessage(), t),
keyNum, sched);
+ }
+ }, NativeThread.MAX_PRIORITY, // ensure this is run before the
callback to remove the request from the running requests list
+ "Internal error");
}
/**