AnsweredAssumed Answered

Inclusive Gateway: Major Performance Issue and Defect

Question asked by tidetom on May 23, 2012
Latest reply on Oct 21, 2013 by jbarrez
Hi all,

I've found a major issue with the Inclusive Gateway.  This is a very different issue (and IMO even more pressing/critical) than ACT-1204, ACT-1026, and ACT-1073 (the currently reported items for Inclusive Gateway), in that it would seem to negate the benefits of using the Inclusive Gateway entirely.

First, to set up the scenario:
  • We have a set of fairly complex flows, with sub-processes that can sometimes be complex as well.  We use inclusive gateways heavily to determine conditional behavior in these flows.

  • It is assumed the reader knows that when an Inclusive Gateway is put into a flow, and it has multiple forks it can take, each fork causes a new activity instruction item to be logged into the Activiti History for that flow.
To summarize the primary issue:
  • After the first Inclusive Gateway path taken, every subsequent task created for that path doesn't have an end_time_ set, and therefore never gets a duration_ set.  Perhaps it never officially ends?

  • The next task (after each of those Inclusive Gateway tasks), is delayed by a minimum of 1 second (sometimes up to 3.5 second task).  See chart below.
First, to see this for yourself on your own flows, add an Inclusive Gateway with several tasks as forks, join using an Inclusive Gateway, then run this handy query:

SELECT r.slevel "Lev",
       act_name_ || ' [' || act_id_ || '}' act_name_id,
       decode(r.slevel, 1, 0, a.duration_) duration,
       decode(r.slevel, 1, a.duration_, 0) "MainTime",
       substr(p.proc_def_id_, 1, instr(p.proc_def_id_, ':') - 1) process,
FROM   act_hi_actinst a,
       (SELECT LEVEL slevel, t.proc_inst_id_, duration_
        FROM   act_hi_procinst t
        START  WITH super_process_instance_id_ IS NULL
             AND    proc_inst_id_ = '1141690'
        CONNECT BY PRIOR proc_inst_id_ = super_process_instance_id_) r,
       act_hi_procinst p
WHERE  a.proc_inst_id_ = r.proc_inst_id_
AND    p.proc_inst_id_ = a.proc_inst_id_

The query should give you a nice output, sequencing your history and showing you every task executed (in order) for a process and all of its sub-processes.  For one of our flows, we have the following statistics:
  • There are 161 process instructions shown in the history.  Of the 162, 23 are related to Inclusive Gateways.  We only have 5 total Inclusive Gateways in the flow.

  • The whole flow takes 53 seconds to execute.  Of the 53 seconds, 36 seconds (68%) are consumed between the start_time_ of Inclusive Gateways, and the start_time_ of the next process instruction (this is the only way duration can be determined, because end_time_ and duration_ aren't set for the Inclusive Gateway).
I have a specific table which shows all 161 generated from the above query, but I think a forum post probably isn't the way to view it.  Instead, I'll put a small sub-segment, from the first (shrunk down to be easier to see):

123  Inclusive Gateway     1317     1.33168000  1.34485000  1317                     0
124  Exclusive Gateway     1        1.34485000  1.34486000  1                        0
125  Verify Something      95       1.34486000  1.34581000  95                       0
126  Exclusive Gateway     0        1.34581000  1.34581000  0                        0
127  Inclusive Gateway              1.34581000              3195                     3195
128  Verify Something Else 70       1.37776000  1.37846000  70                       0
129  Inclusive Gateway              1.37846000              2307                     2307
130  Inclusive Gateway              1.40153000              1669                     1669
131  Update Something      27       1.41822000  1.41849000  47                       20
132  Inclusive Gateway              1.41869000              1417                     1417

Note on the columns:
  • # - The activity instruction number, out of 161.

  • NAME - Taken from the act_name_id in the query above

  • DURATION - Taken from the duration_ in the query above

  • START_TIME - A simplified version of the start_time_ from the query above (in minutes)

  • END_TIME - A simplified version of the end_time_ from the query above (in minutes)

  • START_TO_START_DURATION - The "actual" duration between when the current activity instruction and the next activity instruction is executed

  • DIFFERENCE - The difference between Activiti's duration_, and the "actual" START_TO_START_DURATION.
You can see in the above, that the Exclusive Gateway executes in 1 millisecond.  I would have thought the inclusive gateway would have been the same… but unfortunately as you can see the first execution takes 1.3 seconds.  All subsequent Inclusive Gateway calls do not have a duration, or an end_time, and the "next" activity instruction starts with a significant performance delay.  From 123 to 132 above, it took about 10 seconds to execute.  Only 203 milliseconds of that 10 seconds was spent executing actual business logic, the remainder was spent in delays caused by Inclusive Gateway.

I can certainly enter this as a JIRA issue as well, but wanted to put into the forum to see if there are any immediate thoughts from the community or Activiti development team.

Thanks in advance for your help!