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.java         
>                   (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.


> +               }
> +
> +               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?

> +                       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

Reply via email to