From: <st...@us...> - 2006-11-01 16:10:52
|
Revision: 3554 http://svn.sourceforge.net/smartfrog/?rev=3554&view=rev Author: steve_l Date: 2006-11-01 08:08:55 -0800 (Wed, 01 Nov 2006) Log Message: ----------- Some tuning of the workflow components. 1. not 100% sure that Sequence exits when a child fails half way through 2. Parallel can be made to terminate on startup if there are no children Modified Paths: -------------- trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlock.java trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlockImpl.java trunk/core/smartfrog/src/org/smartfrog/services/assertions/testblock.sf trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/DelayedTerminator.java trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/Parallel.java trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/parallel.sf trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/sequence.sf trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/eventbus/EventCompoundImpl.java Modified: trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlock.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlock.java 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlock.java 2006-11-01 16:08:55 UTC (rev 3554) @@ -59,8 +59,14 @@ String ATTR_TIMEOUT = "timeout"; /** + * Is timeout expected * {@value} */ + String ATTR_EXPECTTIMEOUT = "expectTimeout"; + + /** + * {@value} + */ String ATTR_FORCEDTIMEOUT = "forcedTimeout"; /** * Name that a deployed action goes by Modified: trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlockImpl.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlockImpl.java 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/services/assertions/TestBlockImpl.java 2006-11-01 16:08:55 UTC (rev 3554) @@ -119,10 +119,11 @@ public synchronized void sfStart() throws SmartFrogException, RemoteException { super.sfStart(); long timeout = sfResolve(ATTR_TIMEOUT,0L,true); + boolean expectTimeout=sfResolve(ATTR_EXPECTTIMEOUT,false,true); try { child=sfCreateNewChild(ACTION,action, null); if(timeout>0) { - actionTerminator=new DelayedTerminator(child, timeout, sfLog(),"timeout",false ); + actionTerminator=new DelayedTerminator(child, timeout, sfLog(),"timeout",expectTimeout); } } catch (RemoteException e) { startupException(e); @@ -188,7 +189,10 @@ protected boolean onChildTerminated(TerminationRecord status, Prim comp) throws SmartFrogRuntimeException, RemoteException { if(comp==child) { - //this is the action terminating, so log the closure and continue + //this is the action terminating, + //forget about our now-terminated child (it cannot be serialized any more) + child=null; + //log the closure and continue end(status); return false; } else { Modified: trunk/core/smartfrog/src/org/smartfrog/services/assertions/testblock.sf =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/services/assertions/testblock.sf 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/services/assertions/testblock.sf 2006-11-01 16:08:55 UTC (rev 3554) @@ -45,6 +45,8 @@ sfClass "org.smartfrog.services.assertions.TestBlockImpl"; //timeout in milliseconds timeout 0; + //should timeout be expected? + expectTimeout false; //finished: boolean //status -> exit status Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/DelayedTerminator.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/DelayedTerminator.java 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/DelayedTerminator.java 2006-11-01 16:08:55 UTC (rev 3554) @@ -52,11 +52,11 @@ * Create a delayed time. * If the time is -1, then the wait is for {@link Long#MAX_VALUE}, otherwise it * is for as many milliseconds as needed. - * @param prim - * @param time - * @param log - * @param description - * @param normalTermination + * @param prim component to shut down + * @param time how long to sleep + * @param log a log to log to + * @param description text to use in the termination record (or null to have something made up) + * @param normalTermination should the termination be normal. */ public DelayedTerminator(Prim prim, long time, LogSF log, String description, boolean normalTermination) { if(time<0) { @@ -107,7 +107,7 @@ public synchronized void shutdown(boolean terminateTarget) { if (self != null) { shutdown = true; - this.shouldTerminate = terminateTarget; + shouldTerminate = terminateTarget; self.interrupt(); } } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/Parallel.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/Parallel.java 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/Parallel.java 2006-11-01 16:08:55 UTC (rev 3554) @@ -35,6 +35,7 @@ import org.smartfrog.sfcore.prim.TerminationRecord; import org.smartfrog.sfcore.reference.Reference; import org.smartfrog.sfcore.workflow.eventbus.EventCompoundImpl; +import org.smartfrog.sfcore.utils.ComponentHelper; /** * Parallel is a modified compound which differs in that the sub-components @@ -55,8 +56,11 @@ public class Parallel extends EventCompoundImpl implements Compound { private static Reference asynchCreateChildRef = new Reference ("asynchCreateChild"); - + /** {@value} */ + public static final String ATTR_TERMINATE_IF_EMPTY = "terminateOnEmptyDeploy"; + private static Reference terminateIfEmptyRef = new Reference(ATTR_TERMINATE_IF_EMPTY); private boolean asynchCreateChild=false; + private boolean terminateIfEmpty=false; private Vector asynchChildren = null; /** @@ -64,7 +68,7 @@ * * @throws java.rmi.RemoteException In case of network or RMI failure. */ - public Parallel() throws java.rmi.RemoteException { + public Parallel() throws RemoteException { super(); } @@ -78,6 +82,7 @@ public synchronized void sfDeploy() throws SmartFrogException, RemoteException { super.sfDeploy(); asynchCreateChild = sfResolve(asynchCreateChildRef,asynchCreateChild,false); + terminateIfEmpty = sfResolve(terminateIfEmptyRef, terminateIfEmpty, false); } /** @@ -88,22 +93,36 @@ */ public synchronized void sfStart() throws SmartFrogException, RemoteException { super.sfStart(); - - // let any errors be thrown and caught by SmartFrog for abnormal termination - including empty actions - try { - if (!asynchCreateChild){ - if (sfLog().isDebugEnabled()){sfLog().debug(" Parallel Synch");}; - synchCreateChild(); - } else { - if (sfLog().isDebugEnabled()){sfLog().debug(" Parallel Asynch");}; - asynchCreateChild(); + TerminationRecord terminationRecord = null; + if (!actions.isEmpty()) { +// let any errors be thrown and caught by SmartFrog for abnormal termination - including empty actions + try { + if (!asynchCreateChild){ + if (sfLog().isDebugEnabled()){sfLog().debug(" Parallel Synch");}; + synchCreateChild(); + } else { + if (sfLog().isDebugEnabled()){sfLog().debug(" Parallel Asynch");}; + asynchCreateChild(); + } + } catch (Exception ex) { + if (sfLog().isErrorEnabled()){ + sfLog().error(sfCompleteNameSafe()+" - Failed to start sub-components ",ex); + } + terminationRecord = TerminationRecord + .abnormal("Failed to start sub-components " + ex, name); + //sfTerminate(terminationRecord); } - } catch (Exception ex) { - if (sfLog().isErrorEnabled()){ - sfLog().error(sfCompleteNameSafe()+" - Failed to start sub-components ",ex); + } else { + //no actions. Maybe terminate + if(terminateIfEmpty) { + terminationRecord = new TerminationRecord(TerminationRecord.NORMAL, + "Parallel component is empty",name); } - sfTerminate(TerminationRecord.abnormal("Failed to start sub-components " + ex, name)); } + if (terminationRecord!=null) { + new ComponentHelper(this).targetForWorkflowTermination(terminationRecord); + } + } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/parallel.sf =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/parallel.sf 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/parallel.sf 2006-11-01 16:08:55 UTC (rev 3554) @@ -34,8 +34,14 @@ sfClass "org.smartfrog.sfcore.workflow.combinators.Parallel"; parallelSchema extends Schema { asynchCreateChild extends OptionalBoolean; + terminateOnEmptyDeploy extends OptionalBoolean { + description ##flag which indicates that the parallel component + should terminate immediately if there are no children to deploy#; + } +} } // Deploy children in parallel? Set to true to deploy every child component //in a new thread - asynchCreateChild false; + asynchCreateChild false; + terminateOnEmptyDeploy false; } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/sequence.sf =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/sequence.sf 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/combinators/sequence.sf 2006-11-01 16:08:55 UTC (rev 3554) @@ -22,6 +22,9 @@ /** * the list of the sequence goes into the actions component */ -Sequence extends ActionsCompound { +//Sequence extends ActionCompound { +Sequence extends Compound { sfClass "org.smartfrog.sfcore.workflow.combinators.Sequence"; + sendTo extends LAZY {} + registerWith extends LAZY {} } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/eventbus/EventCompoundImpl.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/eventbus/EventCompoundImpl.java 2006-10-31 17:27:30 UTC (rev 3553) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/workflow/eventbus/EventCompoundImpl.java 2006-11-01 16:08:55 UTC (rev 3554) @@ -44,27 +44,31 @@ */ public class EventCompoundImpl extends CompoundImpl implements EventBus, EventRegistration, EventSink, Compound { - static Reference receiveRef = new Reference( "registerWith"); - static Reference sendRef = new Reference("sendTo"); - Vector receiveFrom = new Vector(); - Vector sendTo = new Vector(); + protected static final String ATTR_REGISTER_WITH = "registerWith"; + protected static final String ATTR_SEND_TO = "sendTo"; + protected static final String ATTR_ACTIONS = "actions"; + protected static final String ATTR_ACTION = "action"; + private static Reference receiveRef = new Reference(ATTR_REGISTER_WITH); + private static Reference sendRef = new Reference(ATTR_SEND_TO); + private Vector receiveFrom = new Vector(); + private Vector sendTo = new Vector(); protected ComponentDescription action=null; protected Context actions=null; protected Enumeration actionKeys=null; + protected Reference name=null; + private boolean oldNotation = true; + private static final Reference actionsRef = new Reference(ATTR_ACTIONS); + private static final Reference actionRef = new Reference(ATTR_ACTION); - boolean oldNotation = true; - static final Reference actionsRef = new Reference("actions"); - static final Reference actionRef = new Reference("action"); - /** * Constructs EventCompoundImpl. * * @throws java.rmi.RemoteException In case of RMI or network failure. */ - public EventCompoundImpl() throws java.rmi.RemoteException { + public EventCompoundImpl() throws RemoteException { super(); } @@ -74,7 +78,7 @@ * If action or actions atributes are present then it behaves like compound and loads all eager components. */ protected void sfDeployWithChildren() throws SmartFrogDeploymentException { - if (sfContext().containsKey("actions")){ + if (sfContext().containsKey(ATTR_ACTIONS)){ oldNotation=true; //Old WF notation using actions // Here follows normal CompoundImpl deployment @@ -200,27 +204,30 @@ super.sfDeploy(); /* find local registrations and register them */ - ComponentDescription sends = (ComponentDescription) sfResolve(sendRef); - Context scxt = sends.sfContext(); + ComponentDescription sends = (ComponentDescription) sfResolve(sendRef,false); + if (sends != null) { + Context scxt = sends.sfContext(); - for (Enumeration e = scxt.keys(); e.hasMoreElements();) { - Object k = e.nextElement(); - Reference l = (Reference) scxt.get(k); - EventSink s = (EventSink) sfResolve(l); - sendTo.addElement(s); + for (Enumeration e = scxt.keys(); e.hasMoreElements();) { + Object k = e.nextElement(); + Reference l = (Reference) scxt.get(k); + EventSink s = (EventSink) sfResolve(l); + sendTo.addElement(s); + } } /* find own registrations, and register remotely */ - ComponentDescription regs = (ComponentDescription) sfResolve(receiveRef); + ComponentDescription regs = (ComponentDescription) sfResolve(receiveRef, false); + if (regs!=null) { + Context rcxt = regs.sfContext(); - Context rcxt = regs.sfContext(); - - for (Enumeration e = rcxt.keys(); e.hasMoreElements();) { - Object k = e.nextElement(); - Reference l = (Reference) rcxt.get(k); - EventRegistration s = (EventRegistration) sfResolve(l); - receiveFrom.addElement(s); - s.register(this); + for (Enumeration e = rcxt.keys(); e.hasMoreElements();) { + Object k = e.nextElement(); + Reference l = (Reference) rcxt.get(k); + EventRegistration s = (EventRegistration) sfResolve(l); + receiveFrom.addElement(s); + s.register(this); + } } if (oldNotation) { @@ -244,8 +251,14 @@ public void sfTerminatedWith(TerminationRecord status, Prim comp) { boolean terminate; if (isWorkflowTerminating()) { - //during termination, always forward - terminate = onWorkflowTerminating(status, comp); + try { + //let subclasses decide what to do here + terminate = onWorkflowTerminating(status, comp); + } catch (Exception e) { + //but if that fails, we terminate + sfLog().error("Exception ", e); + terminate = true; + } } else { //check to see what the subclass wants try { @@ -275,9 +288,12 @@ * @param status exit record of the component * @param comp child component that is terminating * @return true if the termination event is to be forwarded up the chain. + * @throws SmartFrogRuntimeException for runtime exceptions + * @throws RemoteException for network problems */ - protected boolean onWorkflowTerminating(TerminationRecord status, Prim comp) { + protected boolean onWorkflowTerminating(TerminationRecord status, Prim comp) + throws SmartFrogRuntimeException, RemoteException { return true; } @@ -293,6 +309,8 @@ * @param status exit record of the component * @param comp child component that is terminating * @return true if the termination event is to be forwarded up the chain. + * @throws SmartFrogRuntimeException for runtime exceptions + * @throws RemoteException for network problems */ protected boolean onChildTerminated(TerminationRecord status, Prim comp) throws SmartFrogRuntimeException, RemoteException { @@ -308,6 +326,8 @@ * @param status exit record of the component * @param comp non-child component that is terminating * @return true if the component is to be terminated + * @throws SmartFrogRuntimeException for runtime exceptions + * @throws RemoteException for network problems */ protected boolean onNonChildTerminated(TerminationRecord status, Prim comp) throws SmartFrogRuntimeException, RemoteException { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |