> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of Daniel Cheng
> Sent: Monday, March 16, 2009 1:19 AM
> To: [email protected]
> Subject: Re: [freenet-dev] [freenet-cvs] r26044
> -trunk/freenet/src/freenet/pluginmanager
>
> On Sun, Mar 15, 2009 at 11:35 PM, <[email protected]> wrote:
> > Author: xor
> > Date: 2009-03-15 15:35:03 +0000 (Sun, 15 Mar 2009) New
> Revision: 26044
> >
> > Added:
> > trunk/freenet/src/freenet/pluginmanager/PluginTalkerBlocking.java
> > Modified:
> > trunk/freenet/src/freenet/pluginmanager/PluginTalker.java
> > Log:
> > Implement a blocking PluginTalker. This is to be used if
> the result of a FCP call is needed by the caller directly,
> i.e. in UI functions. For example, when creating an identity
> using the Freetalk web interface, we need to show the user
> directly whether the attempt to create it was successful.
> >
> > Modified: trunk/freenet/src/freenet/pluginmanager/PluginTalker.java
> > ===================================================================
> > --- trunk/freenet/src/freenet/pluginmanager/PluginTalker.java
> > 2009-03-14 16:03:52 UTC (rev 26043)
> > +++ trunk/freenet/src/freenet/pluginmanager/PluginTalker.java
> > +++ 2009-03-15 15:35:03 UTC (rev 26044)
> > @@ -15,15 +15,19 @@
> > */
> > public class PluginTalker {
> >
> > - Node node;
> > - private PluginReplySender replysender;
> > + protected Node node;
> > + protected PluginReplySender replysender;
> >
> > - private int access;
> > + protected int access;
> >
> > - FredPluginFCP plugin;
> > + protected FredPluginFCP plugin;
> > + protected String pluginName;
> > + protected String connectionIdentifier;
> >
> > - PluginTalker(FredPluginTalker fpt, Node node2, String
> > pluginname2, String identifier2) throws PluginNotFoundException {
> > + public PluginTalker(FredPluginTalker fpt, Node
> node2, String
> > + pluginname2, String identifier2) throws PluginNotFoundException {
> > node = node2;
> > + pluginName = pluginname2;
> > + connectionIdentifier = identifier2;
> > plugin = findPlugin(pluginname2);
> > access = FredPluginFCP.ACCESS_DIRECT;
> > replysender = new
> PluginReplySenderDirect(node2, fpt,
> > pluginname2, identifier2); @@ -31,12 +35,14 @@
> >
> > public PluginTalker(Node node2, FCPConnectionHandler
> handler,
> > String pluginname2, String identifier2, boolean access2) throws
> > PluginNotFoundException {
> > node = node2;
> > + pluginName = pluginname2;
> > + connectionIdentifier = identifier2;
> > plugin = findPlugin(pluginname2);
> > access = access2 ? FredPluginFCP.ACCESS_FCP_FULL :
> > FredPluginFCP.ACCESS_FCP_RESTRICTED;
> > replysender = new PluginReplySenderFCP(handler,
> > pluginname2, identifier2);
> > }
> >
> > - private FredPluginFCP findPlugin(String pluginname2) throws
> > PluginNotFoundException {
> > + protected FredPluginFCP findPlugin(String
> pluginname2) throws
> > + PluginNotFoundException {
> >
> > Logger.normal(this, "Searching fcp plugin: " +
> > pluginname2);
> > FredPluginFCP plug =
> > node.pluginManager.getFCPPlugin(pluginname2);
> >
> > Added:
> > trunk/freenet/src/freenet/pluginmanager/PluginTalkerBlocking.java
> > ===================================================================
> > ---
> trunk/freenet/src/freenet/pluginmanager/PluginTalkerBlocking.j
> ava
> > (rev 0)
> > +++
> trunk/freenet/src/freenet/pluginmanager/PluginTalkerBlocking.java
> > +++ 2009-03-15 15:35:03 UTC (rev 26044)
> > @@ -0,0 +1,93 @@
> > +/* This code is part of Freenet. It is distributed under the GNU
> > +General
> > + * Public License, version 2 (or at your option any later
> version).
> > +See
> > + * http://www.gnu.org/ for further details of the GPL. */ package
> > +freenet.pluginmanager;
> > +
> > +import freenet.node.Node;
> > +import freenet.support.Logger;
> > +import freenet.support.SimpleFieldSet; import
> > +freenet.support.api.Bucket;
> > +
> > +/**
> > + * A PluginTalker which has a sendBlocking() function
> which directly returns the result of the FCP call to the caller.
> > + * This can be used to simplify code which uses FCP very
> much, especially UI code which needs the result of FCP calls directly.
> > + *
> > + * @author xor
> > + */
> > +public class PluginTalkerBlocking extends PluginTalker {
> > +
> > + public PluginTalkerBlocking(FredPluginTalker
> myPluginTalker,
> > + Node myNode, String myPluginName, String myConnectionIdentifier)
> > + throws PluginNotFoundException {
> > + super(myPluginTalker, myNode, myPluginName,
> > + myConnectionIdentifier);
> > + // TODO Auto-generated constructor stub
> > + }
> > +
> > + public static class Result {
> > + public SimpleFieldSet params;
> > + public Bucket data;
> > +
> > + public Result(SimpleFieldSet myParams,
> Bucket myData)
> > + {
> > + params = myParams;
> > + data = myData;
> > + }
> > + }
> > +
> > + protected class PluginReplySenderBlocking extends
> > + PluginReplySender {
> > +
> > + protected final PluginReplySender
> > + nonBlockingReplySender;
> > + protected volatile Result mResult;
> > +
> > + public PluginReplySenderBlocking() {
> > + super(pluginName, connectionIdentifier);
> > + nonBlockingReplySender = replysender;
> > + }
> > +
> > + @Override
> > + public synchronized void
> send(SimpleFieldSet params,
> > + Bucket bucket) {
> > + if(mResult == null) {
> > + mResult = new
> Result(params, bucket);
> > + notifyAll();
> > + } else {
> > + Logger.error(this,
> > + "PluginTalkerBlocking is being used with a FCP call which
> results in
> > + more than 1 reply");
> > + nonBlockingReplySender.send(params,
> > + bucket);
> > + }
>
> If the user ask for blocking, throw a exception if it can't.
> Don't fallback to async -- the client asked for blocking for a reason.
The exception unfortunately could not be thrown to the caller of
sendBlocking() because it is the plugin which receives the message which
calls send() twice or more and after the first send(), the "Result"-object
is returned to the caller of sendBlocking(), so when the plugin calls send()
a second time, sendBlocking() will already have returned.
Would it be useful to throw the exception at the plugin? I do not think so.
It is legal in FCP to call send() more than once when handling a FCP
message, isn't it?
>
> > + }
> > +
> > + public Result getResult() {
> > + while(mResult == null) {
> > + try {
> > + wait();
>
> this would throw Illegal Monitor State Exception make it synchronized,
>
> > + } catch (InterruptedException e) {
> > + }
> > + }
> > +
> > + return mResult;
> > + }
> > +
> > + }
> > +
> > + /**
> > + * When using sendBlocking(), please make sure that
> you only ever call it for FCP functions which only send() a
> single result!
> > + * Results which are sent by the plugin after the
> first result
> > + are dispatched to the asynchronous onReply() function of your
> > + * FredPluginTalker, however this behavior is
> deprecated and not guranteed to work.
> > + */
> > + public Result sendBlocking(final SimpleFieldSet plugparams,
> > + final Bucket data2) {
> > + final PluginReplySenderBlocking replySender = new
> > + PluginReplySenderBlocking();
> > +
> > + node.executor.execute(new Runnable() {
> > +
>
> Why spawn a thread, if all you want is blocking behaviour?
Hmmmm yea this is right, it doesn't really make sense. The code was
copy-pasted from the non-blocking version, thats the reason.
I am just wondering right now whether it still might make sense to execute
it in a separate thread... well, it would allow us to give the caller of
sendBlocking() a timeout value. Further, we wouldn't be mixing the execution
of plugins into single threads, each thread would clearly belong to one
plugin - I don't know whether this has any more advantages than feeling more
clean?
> > + public void run() {
> > +
> > + try {
> > + plugin.handle(replySender,
> > + plugparams, data2, access);
> > + } catch (Throwable t) {
> > + Logger.error(this, "Caught
> > + error while executing FCP plugin handler", t);
> > + }
> > +
> > + }
> > + }, "PluginTalkerBlocking " + connectionIdentifier);
>
>
>
> > +
> > + return replySender.getResult();
> > + }
> > +
> > +}
> >
> > _______________________________________________
> > cvs mailing list
> > [email protected]
> > http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
> >
> _______________________________________________
> Devl mailing list
> [email protected]
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
_______________________________________________
Devl mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl