One Star

tDie, does not stop job from running

Hi there,
I have created a test job to see how the tDie component can be used in the evaluation of business rules to send an error message to the log and exit the job at a certain point based on one of the checks in the rule failing.


tFixedFlow input has two records defined:

The tJavaRow_1 component has a single line of code:
System.out.println("tJava1: RowID = " + input_row.ID);


The tJavaRow_2 component has a single line of code:
System.out.println("tJava2: RowID = " + input_row.ID);


The Run if connection from tJavaRow_1 to tDie_1 has the following condition:
context.FailTest == true


The tDie_1 component has it's Die message mapped to the context.ReasonJobFailed

The job has the following context variables:
ReasonJobFailed   string   "Business Rule Failed: Reason Description Here..."
FailTest bool true


Now the idea here is to simulate getting the job to exit (die) on the first iteration of tJavaRow_1, and prevent tJavaRow_2 and the second iteration from ever happening.  And also write the message to the log (it would be dynamically assigned in a real scenario).
Here is the output from the log after running the job:
Starting job tDieTest at 18:26 08/10/2015.
connecting to socket on port 3631
connected
tJava1: RowID = 1
tJava2: RowID = null
tJava1: RowID = 2
tJava2: RowID = null
Business Rule Failed: Reasone Description Here
2015-10-08 18:26:58|zJ0IX1|zJ0IX1|zJ0IX1|GESII|tDieTest|Default|5|tDie|tDie_1|Business Rule Failed: Reason Description Here|4
Job tDieTest ended at 18:26 08/10/2015.

So this proves that tDie did not stop the job from continuing because tJava2 (should be tJavaRow in those logs but I wrote it wrong and can't be bothered taking more screen shots for this post) has printed, and both iterations for the two records have executed shown by the RowID logged.
tDie has also executed as you can see by it's message in the log, but has not prevented the job from stopping.
Note: I even tried setting the flag in the Advanced settings of tDie_1 to Exit the JVM immediately, but it made no difference.
My expectation was that tFixedFlowInput would iterate over the first record passing it via the flow to tJavaRow_1 which would then execute it's "Run if" connection and this would return true and then execute tDie_1 and that would stop the job.
What am I doing wrong here?
How can I get this to work as expected.
Thank you for your time,
Scott
5 REPLIES
Community Manager

Re: tDie, does not stop job from running

Hi Scott
You need to redesign the job as seen below:
tFixedFlowInput1--main--tFlowToIterate--iterate--tFixedFlowInput2--main--tJavaRow--runIf--tDie
tFixeFlowInput2: get the current row
tDie: will die once the condition is true for each iteration, we usually set a dynamic condition based on the input data. In this case, if you set it to true by default, it will die after the first iteration.
Best regards
Shong
----------------------------------------------------------
Talend | Data Agility for Modern Business
One Star

Re: tDie, does not stop job from running

Shong,
Thanks for the response mate.  However this still does not have the desired effect.
Here is the new job:

The tFixedFlowInput_2 has the following configuration:

Everything else is the same as before.
Here is the output from the log:
Starting job tDieTest_TakeTwo at 09:25 09/10/2015.
connecting to socket on port 3662
connected
tJava1: RowID = 1
tJava2: RowID = null
Business Rule Failed: Reason Description Here...
2015-10-09 09:25:18|IpQJjK|IpQJjK|IpQJjK|GESII|tDieTest_TakeTwo|Default|5|tDie|tDie_1|Business Rule Failed: Reason Description Here...|4
Job tDieTest_TakeTwo ended at 09:25 09/10/2015.

This shows that tJavaRow_2 is still being executed before the job fails.
Here is my end game, what I want to end up with.  The following job is run as a child job.  The parent job runs a set of jobs, each one evaluating a different business rule and if that rule fails, then the job is spost to die and prevent the parent job from going any further.
The child job is one of those rules and it's design looks like this:

The tJavaRow (Get Business Rule Failed Message) get's an out param from the stored proc run in tMsqlSP (Call Proc to Verify Supplier) and writes it's value to a context variable.  There is a "Run if" from the tJavaRow and if the context variable with the Rule Failed Message is not equal to an empty string, then it is spost to execute the tDie to stop the job and its parent job.  
However that is not happening, so to work out why I build the test job that I started this post with.
Hopefully this gives you a better idea of what I am trying to do, and why your suggestion doesn't work as I need to stop the flow at the tJavaRow component and prevent it from moving forward, but in your example tJavaRow_2 still get's executed.
Regards,
Scott
One Star

Re: tDie, does not stop job from running

Shong,
I have found an approach that will work.  If I put the following code in tJavaRow_1 it stops the flow to tJavaRow_2:

System.out.println("tJava1: RowID = " + input_row.ID);
if (context.FailTest) {
System.out.println(context.ReasonJobFailed);
System.exit(1);
}

Of course the job now becomes more ridicule to understand as this solution does not use the tDie component so it is not easy to see that the job can exist there by just looking at the job design.  You now need to inspect the java components to see what is going on.
Is there an approach that will work with the tDie component?
Regards,
Scott
Fifteen Stars

Re: tDie, does not stop job from running

Since this is a business error and not a Java error, you need to design the job to prevent the data moving beyond the tDie. Unfortunately a tDie linked to a component via a RunIf will not fire before the row has moved to the next component. If you want to design the job so that its structure makes it obvious what is happening, then I would suggest using a tHashInput and tHashOutput components to store the data between separate subjobs. So, where you want your tDie to fire, make sure the next component is a tHashOutput component AND that this component is the last in your subjob. Then use a tHashInput component at the start of the next subjob and link the tHashInput to the last tHashOutput. If you have not used them before, check here (https://help.talend.com/search/all?query=tHashoutput&content-lang=en).
Separating the job into subjobs enables definite separation between processes, so it makes something like this possible.
Of course, a more efficient way of doing this is the way that you suggested with Java. But then you have issues (as you suggested) not being able to tell what is going on. You could add notes to indicate this though.
Rilhia Solutions
One Star

Re: tDie, does not stop job from running

rhall,
Thanks for your input mate.  Efficiency is also important, so I think I will have to go with smart naming of components (eg; call the tJavaRow "DIE If Rule Failed" and good documentation.
Thanks again ;-)
Regards,
Scott