Usefulness3/5
Frequency: 4/5
Power: 3/5
Unintuitiveness: 3/5
Complexity: 3/5

Sub-Processes

Reuse parts of a business process by separating it into sub-processes

last changed at 2021-01-11 18:53:02 (UTC)
Intermediate
Process Design
Splitting Things Up
UiPath

Splitting Things Up

This pattern is part of a series showcasing different techniques to split your business process into smaller pieces. Make sure to check out Splitting Things Up for an overview.

Situation

You created a workflow that implements a general task which is needed in a number of different business processes (e.g. updating business partner information used by sales, accounting, procurement, …).

Now you want to make it easy for the different parts of your company to use the workflow and maintain a single source of truth for what the correct implementation is.

Compare

Before you consider extracting parts of a workflow into a separate process, it is highly recommended to split the workflow into sub-workflows

After you split a process, you might want to use a queue to make communication between the sub-processes easier and more visible.

Long-running workflows are a special case of sub-processes that deserve a separate mention due to their usefulness and complexity.

Common examples

  • Master data updates or creation
  • One part of a process takes much longer than another, so you want to use multiple robots for the long part — i.e. load balancing
  • Recurring tasks like approvals
  • Providing easy-to-use abstractions to other developers who may lack the necessary skills, such as API calls to a machine learning server, or Document Understanding (also see libraries)
  • Attended-unattended handoff
  • Cross-cutting concerns such as archiving documents used in the process
  • Providing a single source of truth for business rules

Solutions

Invoke Process

Invoke Process allows you to run a sub-process in the same context as the parent workflow. It’s very similar to executing a sub-workflow in the same project, but the sub-process can be maintained and updated independently.

Invoke Process
Invoke Process

Availability

UiPath.System.Activities >= 19.6 (19.10 on-premises release)

When to use

  • You need to run the sub-process in the same context as the parent process
  • You want to start splitting up a process with minimal modification
  • To create a “library” that is automatically updated to the newest version, without having to touch all client processes
  • To provide an easier-to-use interface for other developers

When not to use

  • The sub-process has to run on a different machine
  • Early in the development cycle (because debugging the sub-process can be much harder)
  • The set of arguments isn’t stable yet (because changing arguments requires republishing the sub-process)
  • For neatness’ sake (it’s too much work for that)

How to use

  1. Publish the sub-process to Orchestrator
  2. Search and add Invoke Process to the parent workflow
  3. Make sure Process Name matches the process name in Orchestrator exactly
  4. Set the Orchestrator Folder Path (unless you want to look for the process in the same folder)
  5. Configure the arguments and Entry Point if applicable

Comments

  • Arguments have to be created manually (you cannot grab them automatically nor copy&paste them).
  • Arguments must be serializable (e.g. no DataRows)
  • Debugging sub-workflows in the context of the parent workflow is nearly impossible — so best make sure your interfaces are as simple as possible and you can test them in isolation
  • By specifying different entry points, you can use Invoke Process as a sort-of library that will be automatically updated for all parent processes when the process is updated in Orchestrator.
  • Invoke Process is not nearly as well-known as it should be.

Variants

  • Run Parallel Process does something very similar to Invoke Process, but allows the parent process to proceed with execution in parallel. Take care when using this in unattended robots, which consume one runtime license for each process running in parallel. It understandably only works with background processes
  • A package called Inter-Process Communication (IPC) was released in 20.10 that allows communication between the parent and child process when run in parallel.

Exercises

  1. Check the Case Study below.
  2. Create a workflow that uses a sub-process in a different Orchestrator folder.
  3. Use a different entry point than the default.
  4. What are the relative merits of Invoke Process and Run Parallel Process compared to libraries?
  5. Create a pair of processes that use Run Parallel Process and IPC (e.g. a clipper process that copies the selected text from the browser to the clipboard and a worker that searches for it).

Solutions

  • When using Invoke Process, all parent processes consuming it will automatically use the newest available version without having to update them manually.
  • When using libraries, you select a specific version to use, which means developers cannot inadvertently break things for other downstream processes
  • Libraries have a better and easier-to-use developer interface (they are compiled into activities vs specifying arguments manually for sub-processes)
  • In terms of debugging complexity, etc. they are rather similar — both require you to publish a new version to Orchestrator, libraries also require you to update the dependency
  • As a result, libraries are arguably more appropriate for utility-like drop-in capabilities and cross-cutting technical concerns, while sub-processes are better for business concerns where you’re looking for a single source of truth
  • Libraries always run in the same workflow, while sub-processes can be run in parallel

Start Job

Start Job is an activity that allows you to execute a process on an unattended robot.

Start Job
Start Job

Unfortunately, it does not support job arguments — so the only realistic usage scenario I know of is to execute a queue consumer. But since the introduction of queue triggers, even that application seems very questionable.

When to use

  • You have to start a job on an unattended robot that does not need any arguments

When not to use

  • You need job arguments
  • The sub-process should execute in the same context as the parent process

How to use

  1. Publish the sub-process to Orchestrator
  2. Search and add Start Job to the parent workflow
  3. Make sure Process Name matches the process name in Orchestrator exactly
  4. Set the Orchestrator Folder Path (unless you want to look for the process in the same folder)

Comments

  • This activity is mostly legacy and pretty useless these days
  • Post feedback to add argument support for Start Job — this will help build a case for a higher prioritization

Exercises

  1. Start a sub-process that performs some action on an unattended robot.
  2. Discuss the pros and cons of Start Job vs Queue Triggers.

Solutions

  • Start Job can be used without a queue
  • Start Job typically would trigger one execution per queue item, or one execution per run of a queue producer. Queue triggers calculate the number of execution based on the number of queue items. This makes queue triggers more flexible, especially when you have multiple producers.
  • Choices for how many jobs should be started are baked into the design of the queue producer for Start Job, while they are part of the queue definition for queue triggers — the latter is preferable because it is both more flexible as well as visible in Orchestrator
  • Queue triggers allow you more flexibility to batch queue items and can be a source of backpressure to communicate a need to provide more robot runtimes
  • Neither allows process arguments

Start Job And Get Reference

Start Job And Get Reference is normally used together with Wait For Job And Resume in long-running workflows. If you skip the wait for job part, you can, however, abuse utilize it to start an unattended job with arguments (as a slightly hacky replacement for the listless Start Job).

Start Job And Get Reference
Start Job And Get Reference

In case you have read ahead and are worrying about the workflow data being stored in Orchestrator: data is only sent to Orchestrator when the process hits Wait for Job And Resume. So using this trick doesn’t have any significant impact on performance and doesn’t cause any data privacy problems.

Availability

UiPath.Persistence.Activities >= 1.0.1 (19.10 on-premises release)

When to use

  • Whenever you need to start a process on an unattended robot with process arguments

How to use

  1. Publish the sub-process to Orchestrator
  2. Add UiPath.Persistence.Activities to the parent project from the package manager
  3. Search and add Start Job And Get Reference to the parent workflow
  4. Make sure Process Name matches the process name in Orchestrator exactly
  5. Set the Orchestrator Folder Path (unless you want to look for the process in the same folder)
  6. Configure the arguments if applicable

Comments

  • Unfortunately, at the time of writing, custom entry points are not supported.
  • Make sure to document why you are using Persistence activities so it’s not removed by mistake.

Exercises

  1. Modify the case study to use Start Job And Get Reference to allow executing the Worker on an unattended robot.

Case study

We start where sub-workflows left off. Our process is neatly separated into sub-workflows, but the whole process resides in one project.

Our purpose is twofold: first, we want to allow Maggie to simply drop a file with supplier changes into a hot folder and have her attended robot pick it up automatically by using a file trigger.In the real world most customers don’t have attended robots for all of their employees, so this is usually realized with a shared network folder as the hot folder instead (which is regularly polled by unattended robot).

Second, in the long term, we want to offload the actual supplier changes to an unattended robot (using a queue to interface between Maggie’s robot and the unattended one) and we want to prepare the workflow to make that easier.

Considering these design constraints, we will split the workflow into two different projects:

  1. A Worker that performs a single supplier change
  2. A Manager that watches the hot folder, reads the Excel workbook and uses Invoke Process to start the worker

Worker

Let’s start with the worker, which will need very few changes. To begin with, create a copy of the STU SubWorkflows project, rename the folder to STU SubProcesses Worker, open it in Studio and edit the project details accordingly.

We don’t need Main, ReadSupplierChanges, EnterSupplierChanges or the Excel file anymore. Make CreateOrChangeSupplier the default entry point by right-clicking it and hitting Set as Main.If you feel like doing some housekeeping, you can also remove the references to the Excel and Mail activities. Afterwards, the project should look like this:

Supplier Change worker project
Supplier Change worker project

That’s it — we should now have a fully functional workflow that creates or changes a single supplier based on its process arguments. To test it, first supply some default arguments and run it in Studio.

Once you are satisfied that that works, delete the default arguments again so we get an error message if we forget to supply them rather than entering some dummy data into our systems. In a real-world scenario, especially if you have access to Studio Pro, creating a test case instead of using default arguments is preferable.

We’re ready to publish the workflow to Orchestrator. We will run the worker process in the same context as the manager in this case study, but publishing it is still necessary so the manager process can find it.

If possible, I would also recommend to test the process by starting a job with it on an unattended robot, supplying at least two different sets of dummy arguments to test supplier creation and change. Testing the workflow from Orchestrator lets you know if the process will actually work when invoked — catching silly mistakes as early as possible is always a good idea.

Publish dialog
Publish dialog

Make sure you note the process name — we’ll need it soon.

Manager

For the manager, as we did previously, create another copy of the STU SubWorkflows project, change the name, and delete everything but EnterSupplierChanges and ReadSupplierChanges. Keep a copy of the Excel file, which we will need later.

Supplier Change manager project
Supplier Change manager project

Hot Folder

Let’s tackle the hot folder behavior first. Create an argument called HotFolder so we’re able to tell the process from Orchestrator (or Assistant) where it should look for new Excel files.

HotFolder argument
HotFolder argument

To make this a bit nicer, I decided to also add a bit of logic that defaults to a subfolder on the user’s Desktop if the HotFolder argument isn’t provided.

HotFolder as an optional argument
HotFolder as an optional argument

Creating a trigger is not in scope for this pattern, so I’ll assume you are familiar with it.Note that these have nothing to do with Orchestrator triggers. If not, just configure Main as shown below. The only property we have to change is to set ChangeType on the FileChangeTrigger to Created

The assignment should read

args.FileChangeInfo.FullPath
File change trigger
File change trigger

It’s always a good idea to check your assumptions, so execute the workflow and drop a file in the hot folder you configured. If it works, Excel should flash up quickly. It might also make sense to add a Log message to the action so we can log which file we are working on.

Background process

Since 19.10, UiPath robots can execute processes in the background. For attended robots, you can execute as many background processes as you want, plus one foreground process (that needs UI Automation). There is no reason the Manager process has to run in the foreground, so let’s turn it into a background process. This option is only available if you have a recent version of System activities — in 19.10, you had to create a project with the correct template.

Background Process
Background Process

To really make it background-capable, we should also avoid flashing up Excel whenever we read a file, so let’s change our ReadRange inside ReadSupplierRanges.xaml from an Excel ReadRange to a Workbook ReadRange, which directly uses the file without going through Excel and, in fact, does not even need MS Office installed.

Changing the ReadRange to the Workbook version
Changing the ReadRange to the Workbook version

Invoke Process

Now we’re ready to modify EnterSupplierChanges to use our sub-process. This is quite simple in theory: just change the Invoke Workflow File to an Invoke Process. The only problem is that we have to manually spell out all 12 arguments… bummer.

In practice, I find this little annoyance to be the second biggest drawback of Invoke Process (the biggest is that it’s hard to debug). You can modify the XAML file directly with a text editor to kinda circumvent this, but it’s not for the faint of heart.

EnterSupplierChanges workflow
EnterSupplierChanges workflow

As you can see, I also removed the Use Browser, which is not background-compatible. The worker will open and close the browser instead. In this case it’s ok to open and close the browser once per row, but if preparing the environment takes a long time, you should definitely look into Queues which shows you how you can batch these changes.

We can now safely remove the reference to the UiAutomation activities, as well.

Finalize Main

Now all that’s left to do is to use EnterSupplierChanges inside our File change trigger action. I also added a Delete File activity so we can track which files were already handled by the robot. In a later pattern we will see how we can move it to an archive folder instead of deleting it.

Final file trigger
Final file trigger

Final result

If you would like to compare your version to mine or look something up, the source code can be found inside the Splitting Things Up repository: Worker, Manager

Exercises

  1. Modify the Manager process to run the Worker in unattended mode instead
  2. What are the advantages of splitting the worker in such a way that it only enters one supplier at a time rather than passing the data table as an argument? Why aren’t we using a single DataRow?
  3. Could you use Start Job to start the worker?
  4. Are there any other process parts we could split off?

Solutions

  • It allows us to test the worker process in isolation, e.g. from Orchestrator
  • We can see which transaction failed easily by inspecting the arguments
  • It’s a cleaner separation of concerns
  • It makes transitioning to queues easier (in fact, we will be able to leave the worker completely unchanged and only surround it with a wrapper)
  • DataRow cannot be used as a process argument because it’s not serializable
  1. Not without a lot of workarounds, as Start Job does not support process arguments.

  2. We could separate the Manager further into a subprocess that reads the Excel file and another that handles the looping and executes the worker. This would provide little additional value, however, and given the attendant increase in complexity, I wouldn’t recommend it in this case.

It can be useful in other scenarios, however, such as when additional data needs to be gathered in the loop and you want to offload the task to an unattended robot.

References


© 2021, Stefan Reutter