Multiple Instance Atomic  Tasks or Composite Tasks can be used to create a defined or dynamic number of tasks or subnets in a workflow. This can be used to create a work item or subnet  for every element in a list of elements. In combination with other YAWL mechanisms, this can be used to distribute work items to a dynamic list of users or roles during runtime. In this tutorial however, I will show how to create a Multiple Instance Task, that will have as many instances as there are objects in a given list. The mechanism for Multiple Instance Atomic Tasks and Multiple Instance Composite Tasks is the same and the latter will be used to create a whole net with the instantiated variables instead of just a single task.

First, let’s create data types that can be used. I have created four data types:

  • Object is an abstract container of information with a String an a Boolean variable
  • ObjectContainer holds an unlimited number of Objects
  • ObjectWithComment is the Object data type with an additional String “Comment”
  • ObjectWithStringContainer holds an unlimited number of ObjectWithComment

And here is my data type definition:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="Object">
    <xs:sequence>
      <xs:element type="xs:string" name="String" />
      <xs:element type="xs:boolean" name="check" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ObjectContainer">
    <xs:sequence>
      <xs:element type="Object" name="Object" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ObjectWithComment">
    <xs:sequence>
      <xs:element type="xs:string" name="String" />
      <xs:element type="xs:boolean" name="check" />
      <xs:element type="xs:string" name="comment" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ObjectWithCommentContainer">
    <xs:sequence>
      <xs:element type="ObjectWithComment" name="ObjectWithComment" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

The Idea is that there should be as many instances of the task created as there are Objects in the ObjectContainer. In addition these objects should be enriched by a comment  and converted to the ObjectWithComment with it's Container. The words in "name" are the name of the different variable  or task names.

I have created a simple workflow with three tasks. It contains three net variables, one of each container data type named after it and String variable with the name "Test", all three net variables has the usage setting 'local' . The first task("Fill Object Container") is a simple atomic task used to fill the ObjectContainer as an output parameter. Followed by this task should be the Multiple Instance Atomic Task ("Distribute Objects") with the ObjectContainer net variable as input parameter and the ObjectWithCommentContainer net variable as an output parameter. Furthermore the task should contain a task variable("Object") of the Object type and a task variable ("Comment") of the String type. The last task will be used to check if everything worked as intended and has the ObjectWithCommentContainer net variable as an input parameter.

In the editor, the tools for Multiple Instance Atomic Task and Multiple Instance Composite Task can be found next to the symbol for “Add a new Atomic Task” and  Add a new Composite Task” respectively. After a new Multiple Instance Task is created, a right click on it will show the option “Set Instance Detail”. This Option is divided by two tabs. Under “Bounds” you can define the minimum and maximum number of tasks or nets created. Be aware that, if more or less tasks or nets are created then defined error will occur and prevent further execution of the workflow. The "Continuation Threshold" defines after how many completed instances of the task or net the task should be declared as finished to move the the next task in the net. If set to "infinite", then all instances of the multiple instance task or net have to be completed. Instance Creation means, that more instances of the task can be created at runtime after task execution has begun and split into its instances (taken from the YAWL User Manual).

MI1

The next tab "Queries" is more complicated to correctly fill in and be aware that all inputs are case sensitive and often source of errors. It consists of two drop downs and four fields:

  • The first drop down "Multiple Instance Variable" is used to define the task or net variable that will contain the instantiated information that is splitted in the following queries. Here it will be a task variable called "Object" with the type "Object".
  • The second field "Accessor Query" points to the information, that is to be splitted. Here it will point to the net variable containing all Objects. 
  • The third field "Splitter Query" should contain the logic to generate the single objects, that can be distributed to the single instances. In this example the query will split the ObjectContainer it its Object elements.
  • The fourth field "Instance Query" should define the output object of the instance and make sure it is formatted correctly. For this example a new element is created named "ObjectWithComment". It contains all information of the Object element, as well as an additional element called "comment", which will contain the contents of the task variable "comment" of the Multiple Instance Atomic Task.
  • The fifth field "Aggregate Query" puts together all information of all instances into a single list. Here every Object created by the Instance Query should be retruned as is.
  • The sixth and last is the Result Net Variable drop down. Here you choose the net variable that, should contain all aggregated information.  As of version 2.2 it is stated in the manual that outer brackets are optional, however leaving the brackets out resulted in errors for me.

So here is a sceenshot of the Query tab of my Multiple Instance Atomic Task:

 

With that finshed, all that is left is to define a resource for the tasks and upload the specification to the engine.

Attached to this tutorial is the workflow specification.

 

(Notice: This tutorial is based on  YAWL version 2.3.x)

MI.yawl (12.3 KB)

k.schildt

Sun, 12/15/2013 - 13:40

 

The tutorial is well understood, but there is a statement that is irritating.
The variables in the multiple atomic task can not be explained exactly. According to the text you think, you should declare four variables, rather than declare two variables.
 

As next the user don't know, how to name the 3 tasks. He learns it only in  part, if you should  set the "Instance queries".

At last the statement in the Aggregate Query isn't correct. The braces must be omitted. For a succesfull statement.

 

Greetings,

Kai Sch.