ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter reilly <peter.rei...@corvil.com>
Subject Re: Macrodef and parallel in a recursive situation
Date Mon, 20 Oct 2003 11:35:50 GMT
On Monday 20 October 2003 11:43, Jose Alberto Fernandez wrote:
> Peter,
>
> sounds great. How does your implementation using threadLocal
> works when going across <ant> or <antcall>? Just curious.

The local properties do not cross to the ant/antcall project.

They could but I figured that as they are "local", they do
not need to.
Peter

>
> Jose Alberto
>
> > -----Original Message-----
> > From: peter reilly [mailto:peter.reilly@corvil.com]
> > Sent: 20 October 2003 09:59
> > To: Ant Developers List
> > Subject: Re: Macrodef and parallel in a recursive situation
> >
> >
> > I have written the code to support local properties.
> > While I was doing this, I realized that the attributes
> > of a macrodef could/should be local properties as well,
> > removing some of the issues seen last week (use of attribute
> > in a bsf script and support of parallel/recursive).
> >
> > The following shows it in using a new task called local.
> >
> > <project name="local">
> >   <property name="prop1" value="a global value"/>
> >   <target name="test1">
> >     <local name="prop1" value="a local value"/>
> >     <echo>prop1 is "${prop1}"</echo>
> >   </target>
> >   <target name="test2" depends="test1">
> >     <echo>prop1 is "${prop1}"</echo>
> >   </target>
> > </project>
> >
> > This ant test2 generates the following:
> >
> > test1:
> > prop1 is "a local value"
> >
> > test2:
> > prop1 is "a global value"
> >
> > Each taskcontainer sets up a new local scope:
> >
> >   <target name="sequential">
> >     <local name="prop2" value="in target"/>
> >     <sequential>
> >       <local name="prop2" value="in sequential"/>
> >       <echo>prop2 is "${prop2}"</echo>
> >     </sequential>
> >     <echo>prop2 is "${prop2}"</echo>
> >   </target>
> >
> > will generate the following:
> > sequential:
> > prop2 is "in sequential"
> > prop2 is "in target"
> >
> > The value part of <local> is optional, and  the local
> > property may be set by a subsequent <property>, <property>
> > will only set it if the value is not set.
> >
> >   <target name="notset">
> >     <local name="prop3"/>
> >     <echo>prop3 is "${prop3}"</echo>
> >     <property name="prop3" value="is set"/>
> >     <property name="prop3" value="is set again"/>
> >     <echo>prop3 is "${prop3}"</echo>
> >   </target>
> >
> > will generate the following:
> > notset:
> > prop3 is "${prop3}"
> > prop3 is "is set"
> >
> > prop3 is still a local variable and will not be seen outside
> > the target.
> >
> > The local properties are thread local so the following works
> > as expected:
> >   <target name="parallel">
> >     <local name="prop4"/>
> >     <parallel>
> >       <sequential>
> >         <property name="prop4" value="thread1"/>
> >         <echo>t1: prop4 is "${prop4}"</echo>
> >       </sequential>
> >       <sequential>
> >         <property name="prop4" value="thread2"/>
> >         <echo>t2: prop4 is "${prop4}"</echo>
> >       </sequential>
> >       <sequential>
> >         <property name="prop4" value="thread3"/>
> >         <echo>t3: prop4 is "${prop4}"</echo>
> >       </sequential>
> >     </parallel>
> >   </target>
> >
> > parallel:
> > t2: prop4 is "thread2"
> > t1: prop4 is "thread1"
> > t3: prop4 is "thread3"
> >
> > Use with macrodef.
> > -----------------
> >
> > Attributes may now be implemented as local properties, which
> > means that they will be seen as normal properties by ant
> > tasks - including script.
> >
> >   <target name="macro">
> >     <macrodef name="callscript">
> >       <attribute name="x"/>
> >       <sequential>
> >         <script language="beanshell">
> >           System.out.println("x is '" +
> > project.getProperty("x") + "'");
> >         </script>
> >       </sequential>
> >     </macrodef>
> >
> >     <callscript x="this is x"/>
> >   </target>
> >
> > will generate:
> > macro:
> > x is 'this is x'
> >
> > Macrodef does not do the attribute substitutions so the following
> >   <target name="macro2">
> >     <macrodef name="callscript">
> >       <attribute name="x"/>
> >       <sequential>
> >         <script language="beanshell">
> >           System.out.println("x is '${x}'");
> >         </script>
> >       </sequential>
> >     </macrodef>
> >
> >     <callscript x="this is x"/>
> >   </target>
> > will generate:
> > macro2:
> > x is '${x}'
> > as <script/> does not do property expansion.
> >
> > A variation of the recurive macrodef last week may be done by:
> >   <target name="recur">
> >     <macrodef name="recur">
> >       <attribute name="thread"/>
> >       <attribute name="current"/>
> >       <sequential>
> >         <antcontrib:if>
> >           <equals arg1="0" arg2="${current}"/>
> >           <then>
> >             <echo message="Thread: ${thread} done"/>
> >           </then>
> >           <else>
> >             <antcontrib:math
> >               datatype  = "int"
> >               operand1  = "${current}"
> >               operation = "-"
> >               operand2  = "1"
> >               result    = "current"
> >               />
> >             <echo message = "T: ${thread}, C: ${current}" />
> >             <sleep seconds="1"/>
> >             <recur current = "${current}" thread  = "${thread}" />
> >           </else>
> >         </antcontrib:if>
> >       </sequential>
> >     </macrodef>
> >
> >     <parallel>
> >       <recur thread="1" current="5"/>
> >       <recur thread="2" current="6"/>
> >       <recur thread="3" current="2"/>
> >     </parallel>
> >   </target>
> >
> > The output is:
> > recur:
> > T: 3, C: 1
> > T: 1, C: 4
> > T: 2, C: 5
> > T: 3, C: 0
> > T: 1, C: 3
> > T: 2, C: 4
> > Thread: 3 done
> > T: 1, C: 2
> > T: 2, C: 3
> > T: 1, C: 1
> > T: 2, C: 2
> > T: 1, C: 0
> > T: 2, C: 1
> > Thread: 1 done
> > T: 2, C: 0
> > Thread: 2 done
> >
> >
> >
> > I realize that it is late in the day to get this
> > into ant1.6, but I think that it will make macrodef
> > much more usefull and easy to port current antcalls.
> >
> > The changes are quite small (mostly to PropertyHelper).
> >
> > Peter
> >
> > On Saturday 18 October 2003 16:22, Jose Alberto Fernandez wrote:
> > > > From: peter reilly [mailto:peter.reilly@corvil.com]
> > > >
> > > > I think that we may need a thread local variable to
> > > > handle parallel.
> > > >
> > > > This would mean some deep messing with the Property handling.
> > >
> > > I do not see how thread locals would help here. I guess the
> >
> > question
> >
> > > is whether tasks in parallel should be able to modify the global
> > > properties in the frame, or should the changes be local to the
> > > parallel branch (and somehow joined at the end of execution).
> > >
> > > That would mean each parallel computation branch is independent. I
> > > guess I am suggesting the second type of implementation
> >
> > proposed for
> >
> > > <local-property> to be used instead for <parallel>. I think
> >
> > that would
> >
> > > be a much more efficient way to do it. So here is how it would work:
> > >
> > > 1) Add new attribute independent (default false) to <parallel>.
> > >
> > > 2) When independent is true, each thread will use a cloned project
> > > frame for its execution. So all properties and reference
> >
> > manipulation
> >
> > > will be independent of each other. When the thread ends, any new
> > > properties added in the cloned frame, will be added to the original
> > > parent frame, following the common rules for setting
> >
> > properties. Which
> >
> > > means that the first thread that finish will win on setting the
> > > property, if another thread ends later and tries to set the same
> > > variable, it will loose. For references, we need to copy
> >
> > any changes
> >
> > > and due to its semantics all threads will contribute as they end.
> > >
> > > 3) When independent is false, parallel works as today (for backward
> > > compatibility), all threads see each others changes.
> > >
> > > This rules seem easy programable without big changes to CORE.
> > >
> > > I would still like having <local-property> which could be
> >
> > implemented
> >
> > > as per the first description proposed below.
> > >
> > > Jose Alberto
> > >
> > > > Peter
> > > >
> > > > On Friday 17 October 2003 17:57, Jose Alberto Fernandez wrote:
> > > > > > From: peter reilly [mailto:peter.reilly@corvil.com]
> > > > > >
> > > > > > I would rather have Jose's idea of a <local-property/>
task.
> > > > > >
> > > > > > This could be used outside of macrodef.
> > > > > >
> > > > > > The only problem is the implementation.
> > > > >
> > > > > Indeed, there is an easy implementation but will not solve
> > > >
> > > > the case of
> > > >
> > > > > <parallel>, because the local definition would really be a
> > > >
> > > > temporary
> > > >
> > > > > global one:
> > > > >
> > > > > public class LocalProperty extends Sequential {
> > > > >   private String property;
> > > > >   private String oldValue;
> > > > >
> > > > >   public setName(String i_property){property = i_property;}
> > > > >
> > > > >   public void execute() {
> > > > >     if (property == null) throw new BuildException("name
> > > >
> > > > attribute is
> > > >
> > > > > mandatory");
> > > > >     try {
> > > > >       oldValue = getProject().getProperty(property);
> > > > >       getProject().setProperty(property, null); // This
> >
> > may need
> >
> > > > > changes to core
> > > > >       super.execute();
> > > > >     }
> > > > >     finally {
> > > > >       // This is using the deprecated setProperty method
> > > > >       // that actually changes the properties even if set
> > > > >       getProject().setProperty(property, oldValue);
> > > > >     }
> > > > >   }
> > > > > }
> > > > >
> > > > > Here we just change the property value on the project
> > > >
> > > > frame, for the
> > > >
> > > > > duration of the task. And put the old value back before
> >
> > we leave.
> >
> > > > > The problem with this simple implementation is that all the
> > > >
> > > > parallel
> > > >
> > > > > branches will see the change, which is exactly what we were
> > > >
> > > > trying to
> > > >
> > > > > avoid. To do it
> > > > > right, we would need to create a new execution frame that
> > > >
> > > > would be use
> > > >
> > > > > in the
> > > > > "super" call.
> > > > >
> > > > > But if we do that (which is like what <ant> or
> >
> > <antcall> do), what
> >
> > > > > happens if the user defines properties other than the
> > > >
> > > > local-property
> > > >
> > > > > inside the code?
> > > > > Somehow, we would need to find them and propagate them back
> > > >
> > > > to the frame
> > > >
> > > > > above
> > > > > upon exit.
> > > > >
> > > > >   <local-property name="x">
> > > > >    <property name="y" value="myY"/>
> > > > >   <local-property>
> > > > >   <echo message="${y}"/>
> > > > >
> > > > > [echo] myY
> > > > >
> > > > > Doable, but not that easy anymore.
> > > > >
> > > > > What do you guys think?
> > > > >
> > > > > Jose Alberto
> > > > >
> > > > > > Peter
> >
> > ---------------------------------------------------------------------
> >
> > > To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> > > For additional commands, e-mail: dev-help@ant.apache.org
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> > For additional commands, e-mail: dev-help@ant.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message