Topic
  • 13 replies
  • Latest Post - ‏2012-04-22T06:45:12Z by vatsala
Jumbo123
Jumbo123
33 Posts

Pinned topic Condtional Wait Question

‏2012-04-16T13:53:11Z |
Hope , all are doing fine.

I am trying to learn multiinstance looping in IBM BPM 7.5.0. I have created a sample process for this.BPD name is MultiInstanceLoopExample. In the Review Proposal step , I am doing a looping of type multiinstance. Here i have set the Ordering as Run in Parallel and Flow Condition as Conditional Wait(Complex).As per the documentation in infocenter, i was able to see the result.Being motivated, next i wanted to move one step ahead to provide complex conditions to cancel the task in remaining reviewer's inbox if first reviewer provides action as "No".

for that i have written the below code in complex flow condition box and also checked Cancel Remaining Instances checkbox.

var result = true;
+for(var i=0;i<tw.local.reviewers.listLength;i++){+
if(tw.local.reviewers[i].isGoodProposal=="No") {
result=false;
break;
}
else{
result = true;

}
}
result;

Then i created the instance of the BPD and I have two(since two reviewers only) parallel task created for Review Proposal step. But if first reviewer is rejecting the task, the task of second reviewer is not cancelling.. meaning i am able to see second task in process inspector.

Please help me if i am going wrong somewhere. I am sorry if i am little messy while explaining.Also please let me know if you need my import, i will upload.Thanks.
Thanks,
KK
Updated on 2012-04-22T06:45:12Z at 2012-04-22T06:45:12Z by vatsala
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-16T13:59:45Z  
    Onething i just experienced.If i am doing like this after two parallel task are completed, entire BPD is getting completed. I mean to say , as per my BPD, populate Reviewes and Do final review step are not executed at all. Those two activities are getting cancelled.

    KK
  • kolban
    kolban
    3316 Posts

    Re: Condtional Wait Question

    ‏2012-04-16T14:17:07Z  
    Hi there KK,
    I created a simple Human Service and put it in a Multi Instance Loop that caused many instances of it to be created. I checked the return value from any one of the Human Services and if the user had entered "end" in a text field, caused the "Complex Flow Condition" to be true. I also had the "Cancel Remaining Instances" checked. What I found was behavior that we would expect ... all the other task instances were cancelled as desired.

    Looking at your example, I see that you have more than a "simple" expression but instead have a more robust JavaScript fragment. Can you try (for testing purposes) a simple expression and see if a simple response of true causes all your other instances to terminate?

    I'd also add an additional log statement in a script activity following your loop activity to "show" when the loop does terminate.

    Neil
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-17T09:29:21Z  
    • kolban
    • ‏2012-04-16T14:17:07Z
    Hi there KK,
    I created a simple Human Service and put it in a Multi Instance Loop that caused many instances of it to be created. I checked the return value from any one of the Human Services and if the user had entered "end" in a text field, caused the "Complex Flow Condition" to be true. I also had the "Cancel Remaining Instances" checked. What I found was behavior that we would expect ... all the other task instances were cancelled as desired.

    Looking at your example, I see that you have more than a "simple" expression but instead have a more robust JavaScript fragment. Can you try (for testing purposes) a simple expression and see if a simple response of true causes all your other instances to terminate?

    I'd also add an additional log statement in a script activity following your loop activity to "show" when the loop does terminate.

    Neil
    Neil,Thanks a lot.When i am learning, i should learn with simple coding. I tried your suggestion for simple expression for returning true for the loop to terminate.To successfully know loop is terminated , i am writing to log.Here i am just checking with a text field with value "No" for each reviewer by below code in complex flow condition.Everything worked as expected and bpd instance is completed after writing to log.

    code

    var result = false;
    for(var i=0;i<tw.local.reviewers.listLength;i++){
    if(tw.local.comments[i]=="No") {
    result=true;
    break;
    }
    }
    result;


    But when i finished all the task with text field value with other than "No",the BPD instance got completed and log is not printed. I am curious why? Anything wrong here.

    Thanks,
    KK
  • kolban
    kolban
    3316 Posts

    Re: Condtional Wait Question

    ‏2012-04-17T15:25:16Z  
    • Jumbo123
    • ‏2012-04-17T09:29:21Z
    Neil,Thanks a lot.When i am learning, i should learn with simple coding. I tried your suggestion for simple expression for returning true for the loop to terminate.To successfully know loop is terminated , i am writing to log.Here i am just checking with a text field with value "No" for each reviewer by below code in complex flow condition.Everything worked as expected and bpd instance is completed after writing to log.

    code

    var result = false;
    for(var i=0;i<tw.local.reviewers.listLength;i++){
    if(tw.local.comments[i]=="No") {
    result=true;
    break;
    }
    }
    result;


    But when i finished all the task with text field value with other than "No",the BPD instance got completed and log is not printed. I am curious why? Anything wrong here.

    Thanks,
    KK
    Hi there KK,
    I think it would probably help to see much more details. I don't know where the log statement is in relation to the multi-instance loop statement. When I have complex or difficult to understand questions to post to the forum, I commonly create a Word document with pictures and lots and lots of description. I then turn that into a PDF and then post it to the forum posting. That way the reader will have (hopefully) all the information they need in order to provide guidance or info. Providing too little information just means that we have to go back and forth that much more in order to get to an answer which delays the result.

    I do realize that in some cases I am just a "dope" and the information needed to solve the puzzle is already in the posting made so far ... but it is always good to assume that your readers are sometimes dopey :-)

    Neil
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-17T20:21:07Z  
    • kolban
    • ‏2012-04-17T15:25:16Z
    Hi there KK,
    I think it would probably help to see much more details. I don't know where the log statement is in relation to the multi-instance loop statement. When I have complex or difficult to understand questions to post to the forum, I commonly create a Word document with pictures and lots and lots of description. I then turn that into a PDF and then post it to the forum posting. That way the reader will have (hopefully) all the information they need in order to provide guidance or info. Providing too little information just means that we have to go back and forth that much more in order to get to an answer which delays the result.

    I do realize that in some cases I am just a "dope" and the information needed to solve the puzzle is already in the posting made so far ... but it is always good to assume that your readers are sometimes dopey :-)

    Neil
    Hi Neil,

    Surely,I will take the approach of well-documented query as an advice. I have created the the pdf to show steps i am following. Hope i have documented well. If not please let me know.
    Thanks,
    KK
  • kolban
    kolban
    3316 Posts

    Re: Condtional Wait Question

    ‏2012-04-17T21:00:48Z  
    • Jumbo123
    • ‏2012-04-17T20:21:07Z
    Hi Neil,

    Surely,I will take the approach of well-documented query as an advice. I have created the the pdf to show steps i am following. Hope i have documented well. If not please let me know.
    Thanks,
    KK
    Hi KK,
    WOW... that is one of the best write-ups of a problem I have ever seen. I encourage everyone to look at KK's PDF as (what I consider to be) an excellent example of a well written problem description. It is reports like this that illustrate that the poster has spent time on the issue and, as a direct result, I for one am also willing to spend significant time on the issue as I am available.

    I won't swear that I we can get to the end of job in one go ... but ... as I read through the PDF I noticed one possible item.

    Did you ever initialize the "comments" List?

    You have defined "comments" as a "List of String" (aka an Array of String) but I don't see that ever being initialized. Why is that important? Well ... in the step called Generate Reviewers, you populate tw.local.reviewers as a new listOf.String() and add 3 elements.

    Later, in the step called Review Proposal, you have logic that (abstracted) reads:

    for (i=0; i<3; i++)
    {
    if (comments[i] == "No") ...
    }

    But if comments is never initialized to hold 3 strings, we could be in trouble. I would suggest trying:

    tw.local.comments = new tw.object.listOf.String();

    and

    tw.local.comments[i] = "No comment";

    in Generate Reviewers and see what happens.

    Again, this could be non-starter but maybe worth a try. Looking forward to hearing back.

    Neil
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T09:58:17Z  
    • kolban
    • ‏2012-04-17T21:00:48Z
    Hi KK,
    WOW... that is one of the best write-ups of a problem I have ever seen. I encourage everyone to look at KK's PDF as (what I consider to be) an excellent example of a well written problem description. It is reports like this that illustrate that the poster has spent time on the issue and, as a direct result, I for one am also willing to spend significant time on the issue as I am available.

    I won't swear that I we can get to the end of job in one go ... but ... as I read through the PDF I noticed one possible item.

    Did you ever initialize the "comments" List?

    You have defined "comments" as a "List of String" (aka an Array of String) but I don't see that ever being initialized. Why is that important? Well ... in the step called Generate Reviewers, you populate tw.local.reviewers as a new listOf.String() and add 3 elements.

    Later, in the step called Review Proposal, you have logic that (abstracted) reads:

    for (i=0; i<3; i++)
    {
    if (comments[i] == "No") ...
    }

    But if comments is never initialized to hold 3 strings, we could be in trouble. I would suggest trying:

    tw.local.comments = new tw.object.listOf.String();

    and

    tw.local.comments[i] = "No comment";

    in Generate Reviewers and see what happens.

    Again, this could be non-starter but maybe worth a try. Looking forward to hearing back.

    Neil
    Hi Neil,

    Thanks for the suggestion. I have tried to incorporate the best practice(of initializing comments list) as you advised in Generate Reviewers step.Having said that, it is a learning for me and i will keep this in mind when working with list variables.

    But it did not solve the problem.

    Thanks,
    KK
  • SystemAdmin
    SystemAdmin
    7615 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T12:52:28Z  
    • Jumbo123
    • ‏2012-04-18T09:58:17Z
    Hi Neil,

    Thanks for the suggestion. I have tried to incorporate the best practice(of initializing comments list) as you advised in Generate Reviewers step.Having said that, it is a learning for me and i will keep this in mind when working with list variables.

    But it did not solve the problem.

    Thanks,
    KK
    I agree, great write-up. It was only after reading your detailed explanation of what had happen that I was able to spot where you were going wrong. It's a very simple fix, but let me give you the long explanation because I think it can help you understand some things about both MILs and the BPD engine.

    So, to understand what is going on there are two core principles you have to understand: when a multi-instance loop with a complex condition is complete, and when a BPD is complete.

    A multi-instance loop is done when you tell it is done. Every time one of the sub-instances completes it checks the flow condition. If that condition is true, the multi-instance is done. When the multi-instance is done, it cancels the remaining instances (if you tell it to) and then releases a single token to the outgoing flow. What you have implemented in your complex flow is a some Javascript that says the activity is done when one or more of the reviewers says "No".

    A BPD is done where there are no remaining tokens. This sounds obvious, but it can have some interesting subtleties as we shall see.

    So, lets think about the case where you are getting unexpected results. You start the process and get to the point where the MIL is started.

    The first task is completed with the value "hhh". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is not done. Nothing happens. (as expected).

    The second task is completed with the value "jjj". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is not done. Nothing happens. (as expected).

    The third task is completed with the value "kkk". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is STILL not done! So, there is no reason for the BPD engine to proceed to the next task as it's still not done! So that explains the first unexpected thing you are seeing: no task in the check control after MIL coach. But after doing that, the BPD engine looks and it sees that all of the tokens have been removed! So it then marks the entire instance as complete, which is the other thing happening you didn't expect.

    (I remember making this mistake myself back in the day.)

    The Fix

    When you write a complex condition, you are taking responsibility for determining when the activity is done. So you must test for not only the "cancel" conditions, but also the "complete normally" conditions. There are a couple ways to do this. The best way is probably to add a counter integer to the BPD and just increment it every time the flow is testing. Something like :

    var result = false;
    tw.local.loopCount++;
    for(var i=0;i<tw.local.reviewers.listLength;i++){ if(tw.local.comments[i]=="No") {
    result=true; break;
    } }
    if (tw.local.loopCount>=tw.local.reviewers.listLength) {
    result=true;
    }
    result;

    I didn't test my code, and this forum editing text box isn't the best place to write code, so I might have made a stupid syntax error or off-by-one error but you get the idea.

    The Other Warning

    Cancel Remaining Instances is what you want 99.9% of the time. In the strange use cases where you don't want this, you are responsible for not only determining when the MIL is done, but also what to do with all of the extra tokens. This is non-intuitive to most people, but if you uncheck that box then one token will flow out of the MIL every time the complex condition is met. It functions almost like a split would. So you then have to deal with all of those non-canceled tokens in some way or you'll end up with lots of "duplicate" tasks.
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T14:28:09Z  
    I agree, great write-up. It was only after reading your detailed explanation of what had happen that I was able to spot where you were going wrong. It's a very simple fix, but let me give you the long explanation because I think it can help you understand some things about both MILs and the BPD engine.

    So, to understand what is going on there are two core principles you have to understand: when a multi-instance loop with a complex condition is complete, and when a BPD is complete.

    A multi-instance loop is done when you tell it is done. Every time one of the sub-instances completes it checks the flow condition. If that condition is true, the multi-instance is done. When the multi-instance is done, it cancels the remaining instances (if you tell it to) and then releases a single token to the outgoing flow. What you have implemented in your complex flow is a some Javascript that says the activity is done when one or more of the reviewers says "No".

    A BPD is done where there are no remaining tokens. This sounds obvious, but it can have some interesting subtleties as we shall see.

    So, lets think about the case where you are getting unexpected results. You start the process and get to the point where the MIL is started.

    The first task is completed with the value "hhh". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is not done. Nothing happens. (as expected).

    The second task is completed with the value "jjj". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is not done. Nothing happens. (as expected).

    The third task is completed with the value "kkk". First, the system closes the task (removing the token). The BPD engine then checks the complex condition, no one has said No, so the MIL is STILL not done! So, there is no reason for the BPD engine to proceed to the next task as it's still not done! So that explains the first unexpected thing you are seeing: no task in the check control after MIL coach. But after doing that, the BPD engine looks and it sees that all of the tokens have been removed! So it then marks the entire instance as complete, which is the other thing happening you didn't expect.

    (I remember making this mistake myself back in the day.)

    The Fix

    When you write a complex condition, you are taking responsibility for determining when the activity is done. So you must test for not only the "cancel" conditions, but also the "complete normally" conditions. There are a couple ways to do this. The best way is probably to add a counter integer to the BPD and just increment it every time the flow is testing. Something like :

    var result = false;
    tw.local.loopCount++;
    for(var i=0;i<tw.local.reviewers.listLength;i++){ if(tw.local.comments[i]=="No") {
    result=true; break;
    } }
    if (tw.local.loopCount>=tw.local.reviewers.listLength) {
    result=true;
    }
    result;

    I didn't test my code, and this forum editing text box isn't the best place to write code, so I might have made a stupid syntax error or off-by-one error but you get the idea.

    The Other Warning

    Cancel Remaining Instances is what you want 99.9% of the time. In the strange use cases where you don't want this, you are responsible for not only determining when the MIL is done, but also what to do with all of the extra tokens. This is non-intuitive to most people, but if you uncheck that box then one token will flow out of the MIL every time the complex condition is met. It functions almost like a split would. So you then have to deal with all of those non-canceled tokens in some way or you'll end up with lots of "duplicate" tasks.
    WOW... How much i learned from this thread!!!! I realy can't measure.

    Thanks Neil for giving valuable suggestion.

    Thanks David,
    i could get to know the rules of MIL and BPD execution. The suggestion you gave worked fantastic.

    You have mentioned as "So you must test for not only the "cancel" conditions, but also the "complete normally" conditions". For that I tested normally.I could see when i am unchecking the Cancel Remaining Instances check box , the rest two tokens are freezed to MIL-implemented activity although the Check control step is active now. This is what mentioned by you.

    Would you mind giving me small tips on below aspect? Being curious , i am asking this.

    1. Is there any way to Cancel the remaining instances out side of the loop?
    Thanks,
    KK
  • SystemAdmin
    SystemAdmin
    7615 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T15:21:14Z  
    • Jumbo123
    • ‏2012-04-18T14:28:09Z
    WOW... How much i learned from this thread!!!! I realy can't measure.

    Thanks Neil for giving valuable suggestion.

    Thanks David,
    i could get to know the rules of MIL and BPD execution. The suggestion you gave worked fantastic.

    You have mentioned as "So you must test for not only the "cancel" conditions, but also the "complete normally" conditions". For that I tested normally.I could see when i am unchecking the Cancel Remaining Instances check box , the rest two tokens are freezed to MIL-implemented activity although the Check control step is active now. This is what mentioned by you.

    Would you mind giving me small tips on below aspect? Being curious , i am asking this.

    1. Is there any way to Cancel the remaining instances out side of the loop?
    Thanks,
    KK
    I'm not sure I totally understand your question.

    Is your question, "If I am in that odd use case where I don't want to use 'Cancel Remaining Instances', how do I cancel the remaining instances myself"?

    If so, as I mentioned, these aren't common use cases. And each use case might handle the situation differently. But let's try to imagine one as an example.

    Use Case:
    A request is made and three auditors review the request for fraud. If any of them say that there is fraud, we need to immediately start going down an exception path to deal with the fraud. However, we still want the other two auditors to complete their review as we want to record their assessments and potentially use them later in court.

    Possible Implementation:
    We use a MIL to give each of the auditors a task just as in your example. And we use a complex condition very similar to the one we discussed previously to check for either an auditor flagging fraud or all reviews being complete. That way we go down the exception path immediately if one of them flags fraud. The difference is that we want to leave the remaining tokens alive in the MIL so that the other auditors can complete their tasks.

    So, we uncheck the 'cancel remaining instances'. But if we do nothing else, and all three auditors flag fraud, then we will end evaluating our condition as true three times, creating three tokens, and our exception path will get executed three times!

    So we add a boolean variable to the BPD and set it to a default of false. After the MIL we add a decision gateway that branches on that boolean variable. If the boolean hasn't been set (therefore it is the first traversal) we flow token normally. (Assumably to determine whether to go down the fraud exception path.) We also use a "post" activity to set the flag to true. That way if a second or third auditor flags fraud the boolean will have already been set and then decision gateway can flow the excess tokens to an end event.

    In another use case you might want to use a conditional join or some other tool, but it all depends on what unusual circumstance is leading you to not use 'cancel remaining'. In fact, I probably wouldn't even use this non-cancelling implementation here: it's not that intuitive. An event driven subprocess might be a better approach. But "do not cancel" os another tool in your toolbox should you need it.

    David
  • SystemAdmin
    SystemAdmin
    7615 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T15:25:41Z  
    • Jumbo123
    • ‏2012-04-18T14:28:09Z
    WOW... How much i learned from this thread!!!! I realy can't measure.

    Thanks Neil for giving valuable suggestion.

    Thanks David,
    i could get to know the rules of MIL and BPD execution. The suggestion you gave worked fantastic.

    You have mentioned as "So you must test for not only the "cancel" conditions, but also the "complete normally" conditions". For that I tested normally.I could see when i am unchecking the Cancel Remaining Instances check box , the rest two tokens are freezed to MIL-implemented activity although the Check control step is active now. This is what mentioned by you.

    Would you mind giving me small tips on below aspect? Being curious , i am asking this.

    1. Is there any way to Cancel the remaining instances out side of the loop?
    Thanks,
    KK
    I read your answer again, and I think what is confusing me is "the rest two tokens are freezed to MIL-implemented activity ... Is there any way to Cancel the remaining instances out side of the loop? "

    Are you seeing those tokens still alive? And the tasks still active? If so, you probably forgot to leave the 'cancel remaining' checked. It looks checked in your PDF, but maybe it got unchecked after you took the screenshot. Or do you mean that the tasks are still there (just marked complete). If so, that's normal. Tasks are never deleted. For auditing and other reasons, the tasks stay there: they are just closed.

    David
  • Jumbo123
    Jumbo123
    33 Posts

    Re: Condtional Wait Question

    ‏2012-04-18T19:22:56Z  
    I read your answer again, and I think what is confusing me is "the rest two tokens are freezed to MIL-implemented activity ... Is there any way to Cancel the remaining instances out side of the loop? "

    Are you seeing those tokens still alive? And the tasks still active? If so, you probably forgot to leave the 'cancel remaining' checked. It looks checked in your PDF, but maybe it got unchecked after you took the screenshot. Or do you mean that the tasks are still there (just marked complete). If so, that's normal. Tasks are never deleted. For auditing and other reasons, the tasks stay there: they are just closed.

    David
    Hi David,

    Thanks again for excellent explanation. Yes you got it right.My question was :"If I am in that odd use case where I don't want to use 'Cancel Remaining Instances', how do I cancel the remaining instances myself"?
    This got clarified by your Use case example of Auditors flow.I will try to model this use case to BPD so that this will help me learn MIL better.Thanks.
    KK
  • vatsala
    vatsala
    1 Post

    Re: Condtional Wait Question

    ‏2012-04-22T06:45:12Z  
    • Jumbo123
    • ‏2012-04-18T19:22:56Z
    Hi David,

    Thanks again for excellent explanation. Yes you got it right.My question was :"If I am in that odd use case where I don't want to use 'Cancel Remaining Instances', how do I cancel the remaining instances myself"?
    This got clarified by your Use case example of Auditors flow.I will try to model this use case to BPD so that this will help me learn MIL better.Thanks.
    KK
    Hi David,

    Thanks for the detailed explanation on the Multi Instance Loop.

    I am having some challenged addressing the following requirements in case of multiple reviewers. Appreciate any help on this.

    1. Process should continue with the next activity if none of reviewers act upon the request within the due date (due date of the Multi Instance Loop Activity)
    2. Requirement 1 does not apply if one of the reviewers marks the status as "OnHold"
    3. Admin should be able to change the due date using portal

    To address the above, I tried using the timer event and the complex condition. Have challenges with both.

    1. Timer Event: Unable to access the activity due date (Null pointer exception), the due date is accessible if I am not using a multi instance loop.
    2. Complex condition is triggered only when the sub instances complestes.
    3. If I use the custom due date, I will not be able to reflect any portal due date changes.

    Thanks much for any help.

    • Vatsala