Author: toad
Date: 2008-06-20 14:53:36 +0000 (Fri, 20 Jun 2008)
New Revision: 20525
Modified:
branches/db4o/freenet/src/freenet/client/async/ChosenRequest.java
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
branches/db4o/freenet/src/freenet/client/async/OfferedKeysList.java
branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
branches/db4o/freenet/src/freenet/node/RequestScheduler.java
branches/db4o/freenet/src/freenet/node/RequestStarter.java
branches/db4o/freenet/src/freenet/node/SendableGet.java
branches/db4o/freenet/src/freenet/node/SendableRequest.java
branches/db4o/freenet/src/freenet/node/SimpleSendableInsert.java
Log:
Delete the PersistentChosenRequest on the same transaction as running the
callbacks.
Modified: branches/db4o/freenet/src/freenet/client/async/ChosenRequest.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ChosenRequest.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/client/async/ChosenRequest.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -5,6 +5,8 @@
import freenet.keys.ClientKey;
import freenet.keys.Key;
+import freenet.node.NodeClientCore;
+import freenet.node.RequestScheduler;
import freenet.node.SendableRequest;
/**
@@ -29,5 +31,9 @@
this.key = key;
this.ckey = ckey;
}
+
+ public boolean send(NodeClientCore core, RequestScheduler sched) {
+ return request.send(core, sched, this);
+ }
}
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -464,12 +464,14 @@
return choosenPriorityScheduler;
}
- public synchronized void succeeded(final BaseSendableGet succeeded) {
+ public synchronized void succeeded(final BaseSendableGet succeeded,
final ChosenRequest req) {
if(succeeded.persistent()) {
databaseExecutor.execute(new Runnable() {
public void run() {
try {
schedCore.succeeded(succeeded);
+ if(succeeded.persistent())
+
selectorContainer.delete((PersistentChosenRequest)req);
selectorContainer.commit();
} catch (Throwable t) {
Logger.error(this, "Caught "+t,
t);
@@ -649,28 +651,34 @@
return databaseExecutor;
}
- public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name) {
+ public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name, final
ChosenRequest req) {
databaseExecutor.execute(new Runnable() {
public void run() {
get.onFailure(e, keyNum,
ClientRequestScheduler.this, selectorContainer, clientContext);
+ if(get.persistent())
+
selectorContainer.delete((PersistentChosenRequest)req);
selectorContainer.commit();
}
}, prio, name);
}
- public void callFailure(final SendableInsert put, final
LowLevelPutException e, final Object keyNum, int prio, String name) {
+ public void callFailure(final SendableInsert put, final
LowLevelPutException e, final Object keyNum, int prio, String name, final
ChosenRequest req) {
databaseExecutor.execute(new Runnable() {
public void run() {
put.onFailure(e, keyNum, selectorContainer,
clientContext);
+ if(put.persistent())
+
selectorContainer.delete((PersistentChosenRequest)req);
selectorContainer.commit();
}
}, prio, name);
}
- public void callSuccess(final SendableInsert put, final Object keyNum,
int prio, String name) {
+ public void callSuccess(final SendableInsert put, final Object keyNum,
int prio, String name, final ChosenRequest req) {
databaseExecutor.execute(new Runnable() {
public void run() {
put.onSuccess(keyNum, selectorContainer,
clientContext);
+ if(put.persistent())
+
selectorContainer.delete((PersistentChosenRequest)req);
selectorContainer.commit();
}
}, prio, name);
Modified: branches/db4o/freenet/src/freenet/client/async/OfferedKeysList.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/OfferedKeysList.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/client/async/OfferedKeysList.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -142,8 +142,8 @@
Logger.error(this, "Internal error: "+t, t);
}
- public boolean send(NodeClientCore node, RequestScheduler sched, Object
keyNum, ClientKey ckey) {
- Key key = (Key) keyNum;
+ public boolean send(NodeClientCore node, RequestScheduler sched,
ChosenRequest req) {
+ Key key = (Key) req.token;
// Have to cache it in order to propagate it; FIXME
// Don't let a node force us to start a real request for a
specific key.
// We check the datastore, take up offers if any (on a short
timeout), and then quit if we still haven't fetched the data.
Modified:
branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -312,11 +312,11 @@
return finished;
}
- public boolean send(NodeClientCore core, RequestScheduler sched, Object
keyNum, ClientKey ckey) {
+ public boolean send(NodeClientCore core, RequestScheduler sched,
ChosenRequest req) {
// Ignore keyNum, key, since we're only sending one block.
try {
if(logMINOR) Logger.minor(this, "Starting request:
"+this);
- ClientKeyBlock b = (ClientKeyBlock) keyNum;
+ ClientKeyBlock b = (ClientKeyBlock) req.token;
if(b != null)
core.realPut(b, ctx.cacheLocalRequests);
else {
@@ -324,12 +324,12 @@
return false;
}
} catch (LowLevelPutException e) {
- sched.callFailure((SendableInsert) this, e, keyNum,
NativeThread.NORM_PRIORITY, "Insert failed");
+ sched.callFailure((SendableInsert) this, e, req.token,
NativeThread.NORM_PRIORITY, "Insert failed", req);
if(logMINOR) Logger.minor(this, "Request failed:
"+this+" for "+e);
return true;
}
if(logMINOR) Logger.minor(this, "Request succeeded: "+this);
- sched.callSuccess(this, keyNum, NativeThread.NORM_PRIORITY,
"Insert succeeded");
+ sched.callSuccess(this, req.token, NativeThread.NORM_PRIORITY,
"Insert succeeded", req);
return true;
}
Modified: branches/db4o/freenet/src/freenet/node/RequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/RequestScheduler.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/node/RequestScheduler.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -17,9 +17,10 @@
/** Tell the scheduler that a request from a specific RandomGrabArray
succeeded.
* Definition of "succeeded" will vary, but the point is most
schedulers will run another
* request from the parentGrabArray in the near future on the theory
that if one works,
- * another may also work.
+ * another may also work. Also, delete the ChosenRequest if it is
persistent.
+ * @param req The request we ran, which must be deleted.
* */
- public void succeeded(BaseSendableGet get);
+ public void succeeded(BaseSendableGet get, ChosenRequest req);
/**
* After a key has been requested a few times, it is added to the
cooldown queue for
@@ -58,11 +59,17 @@
public PrioritizedSerialExecutor getDatabaseExecutor();
- public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name);
+ /** Call onFailure() on the database thread, then delete the
PersistentChosenRequest. For a non-persistent request,
+ * just call onFailure() immediately. */
+ public void callFailure(final SendableGet get, final
LowLevelGetException e, final Object keyNum, int prio, String name,
ChosenRequest req);
- public void callFailure(final SendableInsert put, final
LowLevelPutException e, final Object keyNum, int prio, String name);
+ /** Call onFailure() on the database thread, then delete the
PersistentChosenRequest. For a non-persistent request,
+ * just call onFailure() immediately. */
+ public void callFailure(final SendableInsert put, final
LowLevelPutException e, final Object keyNum, int prio, String name,
ChosenRequest req);
- public void callSuccess(final SendableInsert put, final Object keyNum,
int prio, String name);
+ /** Call onSuccess() on the database thread, then delete the
PersistentChosenRequest. For a non-persistent request,
+ * just call onFailure() immediately. */
+ public void callSuccess(final SendableInsert put, final Object keyNum,
int prio, String name, ChosenRequest req);
public FECQueue getFECQueue();
Modified: branches/db4o/freenet/src/freenet/node/RequestStarter.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/RequestStarter.java 2008-06-20
14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/node/RequestStarter.java 2008-06-20
14:53:36 UTC (rev 20525)
@@ -218,7 +218,7 @@
private boolean startRequest(ChosenRequest req, boolean logMINOR) {
if((!isInsert) && sched.fetchingKeys().hasKey(req.key)) return
false;
- core.getExecutor().execute(new SenderThread(req.request,
req.token, req.key, req.ckey), "RequestStarter$SenderThread for "+req);
+ core.getExecutor().execute(new SenderThread(req, req.key),
"RequestStarter$SenderThread for "+req);
return true;
}
@@ -237,23 +237,19 @@
private class SenderThread implements Runnable {
- private final SendableRequest req;
- private final Object keyNum;
+ private final ChosenRequest req;
private final Key key;
- private final ClientKey ckey;
- public SenderThread(SendableRequest req, Object keyNum, Key
key, ClientKey ckey) {
+ public SenderThread(ChosenRequest req, Key key) {
this.req = req;
- this.keyNum = keyNum;
this.key = key;
- this.ckey = ckey;
}
public void run() {
try {
freenet.support.Logger.OSThread.logPID(this);
- if(!req.send(core, sched, keyNum, ckey)) {
- if(!req.isCancelled())
+ if(!req.send(core, sched)) {
+ if(!req.request.isCancelled())
Logger.error(this, "run() not able to
send a request on "+req);
else
Logger.normal(this, "run() not able to
send a request on "+req+" - request was cancelled");
Modified: branches/db4o/freenet/src/freenet/node/SendableGet.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/SendableGet.java 2008-06-20
14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/node/SendableGet.java 2008-06-20
14:53:36 UTC (rev 20525)
@@ -6,6 +6,7 @@
import com.db4o.ObjectContainer;
import freenet.client.FetchContext;
+import freenet.client.async.ChosenRequest;
import freenet.client.async.ClientContext;
import freenet.client.async.ClientRequestScheduler;
import freenet.client.async.ClientRequester;
@@ -60,7 +61,9 @@
/** 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, final RequestScheduler sched,
final Object keyNum, ClientKey key) {
+ public boolean send(NodeClientCore core, final RequestScheduler sched,
ChosenRequest req) {
+ Object keyNum = req.token;
+ ClientKey key = req.ckey;
if(key == null) {
Logger.error(this, "Key is null in send(): keyNum =
"+keyNum+" for "+this);
return false;
@@ -72,25 +75,25 @@
if(isCancelled()) {
if(logMINOR) Logger.minor(this, "Cancelled: "+this);
// 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)");
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.CANCELLED), null,
NativeThread.HIGH_PRIORITY, "onFailure(cancelled)", req);
return false;
}
try {
try {
core.realGetKey(key, ctx.localRequestOnly,
ctx.cacheLocalRequests, ctx.ignoreStore);
} catch (final LowLevelGetException e) {
- sched.callFailure(this, e, keyNum,
NativeThread.HIGH_PRIORITY, "onFailure");
+ sched.callFailure(this, e, keyNum,
NativeThread.HIGH_PRIORITY, "onFailure", req);
return true;
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
- sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)");
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)", req);
return true;
}
// Don't call onSuccess(), it will be called for us by
backdoor coalescing.
- sched.succeeded(this);
+ sched.succeeded(this, req);
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
- sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)");
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR), keyNum,
NativeThread.HIGH_PRIORITY, "onFailure(caught throwable)", req);
return true;
}
return true;
@@ -141,7 +144,7 @@
}
public void internalError(final Object keyNum, final Throwable t, final
RequestScheduler sched, ObjectContainer container, ClientContext context) {
- sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR, t.getMessage(), t),
keyNum, NativeThread.MAX_PRIORITY, "Internal error");
+ sched.callFailure(this, new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR, t.getMessage(), t),
keyNum, NativeThread.MAX_PRIORITY, "Internal error", null);
}
/**
Modified: branches/db4o/freenet/src/freenet/node/SendableRequest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/SendableRequest.java 2008-06-20
14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/node/SendableRequest.java 2008-06-20
14:53:36 UTC (rev 20525)
@@ -2,6 +2,7 @@
import com.db4o.ObjectContainer;
+import freenet.client.async.ChosenRequest;
import freenet.client.async.ClientContext;
import freenet.client.async.ClientRequester;
import freenet.keys.ClientKey;
@@ -41,14 +42,16 @@
/** ONLY called by RequestStarter. Start the actual request using the
NodeClientCore
* provided, and the key and key number earlier got from chooseKey().
- * The request itself may have been removed from the overall queue
already.
+ * The request itself may have been removed from the overall queue
already. For
+ * persistent requests, the callbacks will be called on the database
thread, and we
+ * will delete the PersistentChosenRequest from there before committing.
* @param sched The scheduler this request has just been grabbed from.
* @param keyNum The key number that was fed into getKeyObject().
* @param key The key returned from grabKey().
* @param ckey The client key for decoding, if available (mandatory for
SendableGet, null otherwise).
* @return True if a request was sent, false otherwise (in which case
the request will
* be removed if it hasn't already been). */
- public abstract boolean send(NodeClientCore node, RequestScheduler
sched, Object keyNum, ClientKey ckey);
+ public abstract boolean send(NodeClientCore node, RequestScheduler
sched, ChosenRequest request);
/** If true, the request has been cancelled, or has completed, either
way it need not
* be registered any more. isEmpty() on the other hand means there are
no queued blocks.
Modified: branches/db4o/freenet/src/freenet/node/SimpleSendableInsert.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/SimpleSendableInsert.java
2008-06-20 14:51:36 UTC (rev 20524)
+++ branches/db4o/freenet/src/freenet/node/SimpleSendableInsert.java
2008-06-20 14:53:36 UTC (rev 20525)
@@ -5,6 +5,7 @@
import com.db4o.ObjectContainer;
+import freenet.client.async.ChosenRequest;
import freenet.client.async.ClientContext;
import freenet.client.async.ClientRequestScheduler;
import freenet.client.async.ClientRequester;
@@ -67,21 +68,21 @@
return 0;
}
- public boolean send(NodeClientCore core, RequestScheduler sched, Object
keyNum, ClientKey ckey) {
+ public boolean send(NodeClientCore core, RequestScheduler sched,
ChosenRequest req) {
// Ignore keyNum, key, since this is a single block
boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
try {
if(logMINOR) Logger.minor(this, "Starting request:
"+this);
core.realPut(block, shouldCache());
} catch (LowLevelPutException e) {
- sched.callFailure(this, e, keyNum,
NativeThread.NORM_PRIORITY, "SSI callback: failure");
+ sched.callFailure(this, e, req.token,
NativeThread.NORM_PRIORITY, "SSI callback: failure", req);
if(logMINOR) Logger.minor(this, "Request failed:
"+this+" for "+e);
return true;
} finally {
finished = true;
}
if(logMINOR) Logger.minor(this, "Request succeeded: "+this);
- sched.callSuccess(this, keyNum, NativeThread.NORM_PRIORITY,
"SSI callback: success");
+ sched.callSuccess(this, req.token, NativeThread.NORM_PRIORITY,
"SSI callback: success", req);
return true;
}