Make Escalations Smarter

 

K2 blackpearl has a nice way to automatically escalate activities. Say you have an activity which contains a SmartForms Client Event. Because events are fired sequentially within an activity, client events bring a process instance to a standstill until the client event is completed. (The example below contains four events, which are called sequentially. The green backgrounds indicate events which have completed; the blue background indicates the Get Approval Client Event is in progress, and the white indicates the Call Review event has yet to be called.)

MakeEscalationsSmarter-1

K2 was clever to bake in some simple escalations, which can be based on an arbitrary value for elapsed time. If your approver hasn’t taken action in a timely manner, you can have K2 do things like send the process instance to a separate activity, or to nag the approver with reminder messages.

Recently, I was asked if we could shut off the escalation for a specific activity. Several hundred people were about to receive reminders about their applications when the delay was actually on our side, not theirs. Sadly, because the process instances were tied to a specific version of the workflow, deploying a new version with the escalation action deleted or modified would only affect processes instantiated after the new version was deployed. It wasn’t going to do anything to help with the current situation.

The conundrum led me to think about how we could handle a situation like this in the future, and at will. Here’s what I came up with.

Conceptually, I wanted the escalations to trigger as originally designed, but instead of triggering a reminder e-mail action directly, I wanted to send the process instance to an isolated activity that would kick off a reminders process. The reminders process would determine whether a reminder should be sent based on an Environment Field value. If the value was “false,” the reminders process would end; if it was “true,” it would make an IPC call to a communications process, where an e-mail event would be waiting:

MakeEscalationsSmarter-2

Reminder Process

The cornerstone of the alternate escalations process is the new Reminder Process. This process is in charge of evaluating our Environment Field value, and using the result to determine whether we call our Communications Process or not.

A basic Reminder Process might resemble this:

MakeEscalationsSmarter-3

For the Environment Field, I’d recommend using the values True and False as the value. You can name the field just about whatever you’d like — and remember that all values in Environment Fields are String types. I made my Process Data Field a Boolean, and wrapped the ToBoolean() function around the Environment Field value I was examining. But flavor to taste.

Also, note that the Communications Process will be called directly from within the Reminders Process. That means any data you’ll need for the Communications Process — think some basic properties of an e-mail message — are going to need to be resident within the Reminders Process.

You may also wish to establish multiple types of reminders (you might differentiate between reminders going out to customers and internal reminders intended for staff). That could mean including error handling for invalid reminder types:

MakeEscalationsSmarter-4

Communication Process

Of course, if we’re going to have a Reminder Process to tell the Process Instance whether we want to send e-mail messages, we’re going to need a process to send the actual messages.

One way to do this is to have message templates in place in your communications process, complete with subject and body content, that just needs to be coupled with addressee information passed along from the Reminders Process. That way, the Main Process just passes recipient information and an indicator or two (like the aforementioned Reminder Type) to the Reminders Process via the interprocess call (IPC), and the Communications Process will receive it via its IPC (if reminders are enabled).

A basic Communications Process would really only require an Activity with events to do some validation on the data passed in from the Reminders Process; an Activity which contains one or more E-mail Events, pre-populated with your content, and an End Activity (perhaps only containing a Placeholder Event).

Ideally, you’ll use this Communications Process to handle ALL of your incoming and outgoing message traffic, so think re-use way beyond the scope of reminder traffic — and validation for all kinds of situations. (Are the recipients’ e-mail addresses present? Are they all valid?)

In the example below, you’re looking at a portion of a Communications Process that takes outbound traffic from multiple processes (it uses a data field called “ProcessSource”). This part shows the path(s) associated with the Reminder Process:

MakeEscalationsSmarter-5

Main Process Modifications

We need some changes to our original process in order to support the new Reminder and Communications processes. Each of your Activities containing Client Events is eligible for the upgrade. In the example below, I’m reworking an Activity called “Wait for Correction.”

The trick here is to ensure that the IPC event spawning the Reminder Process is as isolated as possible. In an ecosystem that’s designed to be as interconnected as possible, it’s a messy idea. My solution: Good ol’ “1=0”:

MakeEscalationsSmarter-6

In the example above, the Wait for Correction Activity (pictured in blue) is in the Main Process, and simply contains a Client Event. Flowing into the Activity are several lines coming from any of five error activities above. The outcome of the Client Event is depicted in the line exiting the Activity to the left. (In the actual diagram, this activity is in the lower right corner, routing traffic across the bottom and back up as applicable. I’ll post about this subsystem sometime.)

The Activity has two Escalation Rules — one for a daily e-mail that gets sent on days 1 through 59, and another escalation rule that kills the process instance on day 60 (using an Expire Activity Action).

In its original configuration, the Escalation Rule for the daily reminder simply calls an E-mail Action. The Escalation Rule affords us the ability to send an e-mail message every day the Process Instance remains captive within the Wait for Correction Activity.

In its revised configuration, the Wait for Correction Activity has another Activity joined to it. What’s critical about the link between the two is the line rule:

MakeEscalationsSmarter-7

With this rule in place, it should be impossible for a Process Instance to flow into the Wait for Correction Reminders Activity.

Now, we need to reconfigure the daily reminders Escalation Rule to use a Go To Activity Action instead of an E-mail Action. The Go To Activity Action points to — you guessed it — the Wait for Correction Reminders Activity.

In summary, the Wait for Correction Reminders Activity is only reachable via the Go to Activity Action, which is called once each day the Process Instance remains inside the Wait for Correction Activity.

If the Process Instance is placed within the Wait for Correction Reminders Activity, its Asynchronous IPC is triggered, which instantiates the Reminders Process.   Because the process is called asynchronously, the main process does not wait for the Reminders Process Instance to complete — it is routed right back up to the Wait for Correction Activity. Meanwhile, data is mapped to the various fields declared for the Reminders Process, and a Process Instance is created.

Putting it All Together

Let’s deploy this to our development environment, create a Process Instance, and leave it be long enough to trigger our Escalation Rule. (You might consider setting the time interval to something very short — say, three minutes — so you don’t have to wait forever to test your new code. You want the interval to be long enough so that you can see it pause on the Client Event before jumping out to the IPC Event in the adjacent Activity.)

Open your Workspace. When your Process Instance appears on your worklist, open its ViewFlow. Now drive your Process Instance to your modified Client Event. Here’s what should happen:

  1. At the interval you specified, you should see the Process Instance jump out of your Client Event Activity and into the Activity containing the Reminders Process IPC. (If you saw the Process Instance go straight to the “Reminders” Activity, you should check the Line Rule connecting the two Activities.)

  2. Back in your Workspace, click Process Overview and look for your Reports Process in the report. (Don’t see it? You may have to check to ensure your main process has permission to launch it; resolve that under Management Console > {main node} > Workflow Server > Processes > {the project name of your main process} > Reminder Process > Process Rights. Then start another test.) You should see one instance of the Reports Process in the Process Overview report.

  3. If you saw your Reports Process in the Process Overview report, look for your Communications Process. If you don’t see it, re-run the report — you may have run the report before the Process Instance had moved into the Communications Process. (Don’t see it? Try the permissions thing described above, then start another test.) You should see 1 instance of the Communications Process in the Process Overview Report. Don’t close the Workspace just yet.

  4. Did you expect to receive an e-mail? Look at the Process Instance in your Communications Process and check your Process Data Fields to learn whether your Environment Field was evaluated properly.

  5. Try changing the Environment Field value and re-running your test.