Author: toad
Date: 2008-06-17 18:01:05 +0000 (Tue, 17 Jun 2008)
New Revision: 20408
Modified:
branches/db4o/freenet/src/freenet/clients/http/QueueToadlet.java
branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java
branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java
Log:
Almost fixed QueueToadlet
Modified: branches/db4o/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/QueueToadlet.java
2008-06-17 17:30:09 UTC (rev 20407)
+++ branches/db4o/freenet/src/freenet/clients/http/QueueToadlet.java
2008-06-17 18:01:05 UTC (rev 20408)
@@ -26,8 +26,13 @@
import java.util.LinkedList;
import java.util.List;
+import com.db4o.ObjectContainer;
+
import freenet.client.DefaultMIMETypes;
import freenet.client.HighLevelSimpleClient;
+import freenet.client.MetadataUnresolvedException;
+import freenet.client.async.ClientContext;
+import freenet.client.async.DBJob;
import freenet.keys.FreenetURI;
import freenet.l10n.L10n;
import freenet.node.NodeClientCore;
@@ -54,6 +59,7 @@
import freenet.support.io.BucketTools;
import freenet.support.io.Closer;
import freenet.support.io.FileBucket;
+import freenet.support.io.NativeThread;
public class QueueToadlet extends Toadlet implements RequestCompletionCallback
{
@@ -202,7 +208,7 @@
String persistence =
request.getPartAsString("persistence", 32);
String returnType =
request.getPartAsString("return-type", 32);
try {
-
fcp.makePersistentGlobalRequest(fetchURI, expectedMIMEType, persistence,
returnType);
+
fcp.makePersistentGlobalRequestBlocking(fetchURI, expectedMIMEType,
persistence, returnType);
} catch (NotAllowedException e) {
this.writeError(L10n.getString("QueueToadlet.errorDToDisk"),
L10n.getString("QueueToadlet.errorDToDiskConfig"), ctx);
return;
@@ -212,14 +218,7 @@
} else if (request.isPartSet("change_priority")) {
String identifier =
request.getPartAsString("identifier", MAX_IDENTIFIER_LENGTH);
short newPriority =
Short.parseShort(request.getPartAsString("priority", 32));
- ClientRequest[] clientRequests =
fcp.getGlobalRequests();
-loop: for (int requestIndex = 0, requestCount =
clientRequests.length; requestIndex < requestCount; requestIndex++) {
- ClientRequest clientRequest =
clientRequests[requestIndex];
- if
(clientRequest.getIdentifier().equals(identifier)) {
-
clientRequest.modifyRequest(null, newPriority); // no new ClientToken
- break loop;
- }
- }
+ fcp.modifyGlobalRequestBlocking(identifier,
null, newPriority);
writePermanentRedirect(ctx, "Done", "/queue/");
return;
} else if (request.getPartAsString("insert",
128).length() > 0) {
@@ -253,11 +252,13 @@
/* copy bucket data */
Bucket copiedBucket =
core.persistentEncryptedTempBucketFactory.makeBucket(file.getData().size());
BucketTools.copy(file.getData(), copiedBucket);
+ final ClientPut clientPut;
try {
- ClientPut clientPut = new
ClientPut(fcp.getGlobalForeverClient(), insertURI, identifier,
Integer.MAX_VALUE, RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS,
ClientRequest.PERSIST_FOREVER, null, false, !compress, -1,
ClientPutMessage.UPLOAD_FROM_DIRECT, null, file.getContentType(), copiedBucket,
null, fnam, false);
- clientPut.start();
+ clientPut = new
ClientPut(fcp.getGlobalForeverClient(), insertURI, identifier,
Integer.MAX_VALUE, RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS,
ClientRequest.PERSIST_FOREVER, null, false, !compress, -1,
ClientPutMessage.UPLOAD_FROM_DIRECT, null, file.getContentType(), copiedBucket,
null, fnam, false, fcp);
} catch (IdentifierCollisionException e) {
- e.printStackTrace();
+ Logger.error(this, "Cannot put same
file twice in same millisecond");
+ writePermanentRedirect(ctx, "Done",
"/queue/");
+ return;
} catch (NotAllowedException e) {
this.writeError(L10n.getString("QueueToadlet.errorAccessDenied"),
L10n.getString("QueueToadlet.errorAccessDeniedFile", new String[]{ "file" },
new String[]{ file.getFilename() }), ctx);
return;
@@ -267,7 +268,14 @@
} catch (MalformedURLException mue1) {
writeError(L10n.getString("QueueToadlet.errorInvalidURI"),
L10n.getString("QueueToadlet.errorInvalidURIToU"), ctx);
return;
+ } catch (MetadataUnresolvedException e) {
+ Logger.error(this, "Unresolved metadata
in starting insert from data uploaded from browser: "+e, e);
+ writePermanentRedirect(ctx, "Done",
"/queue/");
+ return;
+ // FIXME should this be a proper
localised message? It shouldn't happen... but we'd like to get reports if it
does.
}
+ if(clientPut != null)
+ fcp.startBlocking(clientPut);
writePermanentRedirect(ctx, "Done", "/queue/");
return;
} else if (request.isPartSet("insert-local-file")) {
@@ -289,12 +297,14 @@
String target = file.getName();
if(!furi.getKeyType().equals("CHK"))
target = null;
+ final ClientPut clientPut;
try {
- ClientPut clientPut = new
ClientPut(fcp.getGlobalClient(), furi, identifier, Integer.MAX_VALUE,
RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS, ClientRequest.PERSIST_FOREVER,
null, false, false, -1, ClientPutMessage.UPLOAD_FROM_DISK, file, contentType,
new FileBucket(file, true, false, false, false, false), null, target, false);
+ clientPut = new
ClientPut(fcp.getGlobalForeverClient(), furi, identifier, Integer.MAX_VALUE,
RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS, ClientRequest.PERSIST_FOREVER,
null, false, false, -1, ClientPutMessage.UPLOAD_FROM_DISK, file, contentType,
new FileBucket(file, true, false, false, false, false), null, target, false,
fcp);
if(logMINOR) Logger.minor(this,
"Started global request to insert "+file+" to CHK@ as "+identifier);
- clientPut.start();
} catch (IdentifierCollisionException e) {
- e.printStackTrace();
+ Logger.error(this, "Cannot put same
file twice in same millisecond");
+ writePermanentRedirect(ctx, "Done",
"/queue/");
+ return;
} catch (MalformedURLException e) {
writeError(L10n.getString("QueueToadlet.errorInvalidURI"),
L10n.getString("QueueToadlet.errorInvalidURIToU"), ctx);
return;
@@ -304,7 +314,13 @@
} catch (NotAllowedException e) {
this.writeError(L10n.getString("QueueToadlet.errorAccessDenied"),
L10n.getString("QueueToadlet.errorAccessDeniedFile", new String[]{ "file" },
new String[]{ file.getName() }), ctx);
return;
+ } catch (MetadataUnresolvedException e) {
+ Logger.error(this, "Unresolved metadata
in starting insert from data from file: "+e, e);
+ writePermanentRedirect(ctx, "Done",
"/queue/");
+ return;
+ // FIXME should this be a proper
localised message? It shouldn't happen... but we'd like to get reports if it
does.
}
+ fcp.startBlocking(clientPut);
writePermanentRedirect(ctx, "Done", "/queue/");
return;
} else if (request.isPartSet("insert-local-dir")) {
@@ -322,12 +338,14 @@
return;
}
}
+ ClientPutDir clientPutDir;
try {
- ClientPutDir clientPutDir = new
ClientPutDir(fcp.getGlobalClient(), furi, identifier, Integer.MAX_VALUE,
RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS, ClientRequest.PERSIST_FOREVER,
null, false, false, -1, file, null, false, true, false);
+ clientPutDir = new
ClientPutDir(fcp.getGlobalForeverClient(), furi, identifier, Integer.MAX_VALUE,
RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS, ClientRequest.PERSIST_FOREVER,
null, false, false, -1, file, null, false, true, false, fcp);
if(logMINOR) Logger.minor(this,
"Started global request to insert dir "+file+" to "+furi+" as "+identifier);
- clientPutDir.start();
} catch (IdentifierCollisionException e) {
- e.printStackTrace();
+ Logger.error(this, "Cannot put same
directory twice in same millisecond");
+ writePermanentRedirect(ctx, "Done",
"/queue/");
+ return;
} catch (MalformedURLException e) {
writeError(L10n.getString("QueueToadlet.errorInvalidURI"),
L10n.getString("QueueToadlet.errorInvalidURIToU"), ctx);
return;
@@ -335,6 +353,7 @@
this.writeError(L10n.getString("QueueToadlet.errorNoFileOrCannotRead"),
L10n.getString("QueueToadlet.errorAccessDeniedFile", new String[]{ "file" },
new String[]{ file.toString() }), ctx);
return;
}
+ fcp.startBlocking(clientPutDir);
writePermanentRedirect(ctx, "Done", "/queue/");
return;
} else if (request.isPartSet("get")) {
Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java 2008-06-17
17:30:09 UTC (rev 20407)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java 2008-06-17
18:01:05 UTC (rev 20408)
@@ -97,12 +97,13 @@
* @throws NotAllowedException
* @throws FileNotFoundException
* @throws MalformedURLException
+ * @throws MetadataUnresolvedException
* @throws InsertException
*/
public ClientPut(FCPClient globalClient, FreenetURI uri, String
identifier, int verbosity,
short priorityClass, short persistenceType, String
clientToken, boolean getCHKOnly,
boolean dontCompress, int maxRetries, short
uploadFromType, File origFilename, String contentType,
- Bucket data, FreenetURI redirectTarget, String
targetFilename, boolean earlyEncode, FCPServer server) throws
IdentifierCollisionException, NotAllowedException, FileNotFoundException,
MalformedURLException, InsertException {
+ Bucket data, FreenetURI redirectTarget, String
targetFilename, boolean earlyEncode, FCPServer server) throws
IdentifierCollisionException, NotAllowedException, FileNotFoundException,
MalformedURLException, MetadataUnresolvedException {
super(uri, identifier, verbosity, null, globalClient,
priorityClass, persistenceType, null, true, getCHKOnly, dontCompress,
maxRetries, earlyEncode, server);
if(uploadFromType == ClientPutMessage.UPLOAD_FROM_DISK) {
if(!server.core.allowUploadFrom(origFilename))
@@ -128,16 +129,7 @@
this.targetURI = redirectTarget;
Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT,
targetURI, cm);
byte[] d;
- try {
- d = m.writeToByteArray();
- } catch (MetadataUnresolvedException e) {
- // Impossible
- Logger.error(this, "Impossible: "+e, e);
- this.data = null;
- clientMetadata = cm;
- putter = null;
- throw new
InsertException(InsertException.INTERNAL_ERROR, "Impossible: "+e+" in
ClientPut", null);
- }
+ d = m.writeToByteArray();
tempData = new SimpleReadOnlyArrayBucket(d);
isMetadata = true;
} else
Modified: branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java 2008-06-17
17:30:09 UTC (rev 20407)
+++ branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java 2008-06-17
18:01:05 UTC (rev 20408)
@@ -644,6 +644,103 @@
}
}
+ public void makePersistentGlobalRequestBlocking(final FreenetURI
fetchURI, final String expectedMimeType, final String persistenceTypeString,
final String returnTypeString) throws NotAllowedException, IOException {
+ class OutputWrapper {
+ NotAllowedException ne;
+ IOException ioe;
+ boolean done;
+ }
+
+ final OutputWrapper ow = new OutputWrapper();
+ core.clientContext.jobRunner.queue(new DBJob() {
+
+ public void run(ObjectContainer container,
ClientContext context) {
+ NotAllowedException ne = null;
+ IOException ioe = null;
+ try {
+ makePersistentGlobalRequest(fetchURI,
expectedMimeType, persistenceTypeString, returnTypeString, container);
+ } catch (NotAllowedException e) {
+ ne = e;
+ } catch (IOException e) {
+ ioe = e;
+ } catch (Throwable t) {
+ // Unexpected and severe, might even be
OOM, just log it.
+ Logger.error(this, "Failed to make
persistent request: "+t, t);
+ } finally {
+ synchronized(ow) {
+ ow.ne = ne;
+ ow.ioe = ioe;
+ ow.done = true;
+ ow.notifyAll();
+ }
+ }
+ }
+
+ }, NativeThread.HIGH_PRIORITY, false);
+
+ synchronized(ow) {
+ while(true) {
+ if(!ow.done) {
+ try {
+ ow.wait();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ continue;
+ }
+ if(ow.ioe != null) throw ow.ioe;
+ if(ow.ne != null) throw ow.ne;
+ return;
+ }
+ }
+ }
+
+ public boolean modifyGlobalRequestBlocking(final String identifier,
final String newToken, final short newPriority) {
+ ClientRequest req =
this.globalRebootClient.getRequest(identifier, null);
+ if(req != null) {
+ req.modifyRequest(newToken, newPriority, this, null);
+ return true;
+ } else {
+ class OutputWrapper {
+ boolean success;
+ boolean done;
+ }
+ final OutputWrapper ow = new OutputWrapper();
+ core.clientContext.jobRunner.queue(new DBJob() {
+
+ public void run(ObjectContainer container,
ClientContext context) {
+ boolean success = false;
+ try {
+ ClientRequest req =
globalForeverClient.getRequest(identifier, container);
+ if(req != null)
+
req.modifyRequest(newToken, newPriority, FCPServer.this, container);
+ } finally {
+ synchronized(ow) {
+ ow.success = success;
+ ow.done = true;
+ ow.notifyAll();
+ }
+ }
+ }
+
+ }, NativeThread.HIGH_PRIORITY, false);
+
+ synchronized(ow) {
+ while(true) {
+ if(!ow.done) {
+ try {
+ ow.wait();
+ } catch (InterruptedException
e) {
+ // Ignore
+ }
+ continue;
+ }
+ return ow.success;
+ }
+ }
+ }
+ }
+
/**
* Create a persistent globally-queued request for a file.
* @param fetchURI The file to fetch.
@@ -794,5 +891,44 @@
if(globalRebootClient.setRequestCompletionCallback(cb) != null)
Logger.error(this, "Replacing request completion
callback "+cb, new Exception("error"));
}
-
+
+ public void startBlocking(final ClientRequest req) {
+ if(req.persistenceType == ClientRequest.PERSIST_REBOOT) {
+ req.start(null, core.clientContext);
+ } else {
+ class OutputWrapper {
+ boolean done;
+ }
+ final OutputWrapper ow = new OutputWrapper();
+ core.clientContext.jobRunner.queue(new DBJob() {
+
+ public void run(ObjectContainer container,
ClientContext context) {
+ try {
+ req.start(container, context);
+ } finally {
+ synchronized(ow) {
+ ow.done = true;
+ ow.notifyAll();
+ }
+ }
+ }
+
+ }, NativeThread.HIGH_PRIORITY, false);
+
+ synchronized(ow) {
+ while(true) {
+ if(!ow.done) {
+ try {
+ ow.wait();
+ } catch (InterruptedException
e) {
+ // Ignore
+ }
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ }
+
}