Advanced Features

This section covers advanced workflow features for complex business process modeling.

Table of Contents

Super States

Super states (also called composite states) allow you to create nested state machines, reducing duplication and creating cleaner workflow designs.

Concept

A super state is a state that contains other states (sub-states). Sub-states inherit transitions from their parent super state, eliminating the need to duplicate transitions.

Think of it like object-oriented inheritance: - Super state = Parent class - Sub-states = Child classes - Transitions from super state = Inherited methods

When to Use Super States

Use super states when: - Multiple states share common transitions (error handling, cancellation, timeout) - You need to model hierarchical processes - You want to reduce visual clutter in complex workflows - States have similar behavior with minor variations

Example scenarios: - All processing states can be cancelled → Create “Processing” super state - Multiple approval levels share timeout logic → Create “Pending Approval” super state - Different work states share error handling → Create “Active Work” super state

Creating Super States

In the Workflow Designer:

  1. Create the super state (e.g., “InProgress”)
  2. Create sub-states (e.g., “Filling”, “Capping”, “Labeling”)
  3. For each sub-state, set Super State property to the super state
  4. Add transitions to the super state (these are inherited by all sub-states)
  5. Add specific transitions to individual sub-states as needed

Example: Bottle Filling Process

Without Super States (Duplicated Transitions):

Empty ──fill──> Filling ──cap──> Capping ──label──> Labeling ──complete──> Full
  │               │                 │                   │
  └─reset─────────┴─reset───────────┴─reset─────────────┘
  │               │                 │                   │
  └─break─────────┴─break───────────┴─break─────────────┘

Problems: - reset transition duplicated 3 times - break transition duplicated 3 times - Hard to maintain (change requires updating 3 places)

With Super States (Clean Design):

Empty ──fill──> InProgress ──complete──> Full
                    │
                    ├─reset──> Empty
                    ├─break──> Broken
                    │
                    └─[Sub-states]
                        ├─> Filling ──cap──> Capping
                        └─> Capping ──label──> Labeling
                        └─> Labeling

Benefits: - reset and break defined once on InProgress super state - All sub-states inherit these transitions - Easier to maintain and understand - Reduced visual complexity

Configuration

Super State Properties: - Label: “InProgress” - OnEntry: Chain to execute when entering any sub-state - OnExit: Chain to execute when leaving any sub-state - OnAfter: Deferred event for all sub-states

Sub-State Properties: - Label: “Filling” - Super State: “InProgress” (dropdown selection) - OnEntry: Chain specific to this sub-state - OnExit: Chain specific to this sub-state

Transition Inheritance: - Transitions from super state apply to all sub-states - Sub-state specific transitions take precedence - Transitions between sub-states stay within super state

Advanced Pattern: Error Handling

Use super states to centralize error handling:

Start ──> Processing (Super State) ──success──> Completed
              │
              ├─error──> Failed
              ├─timeout──> TimedOut
              ├─cancel──> Cancelled
              │
              └─[Sub-states]
                  ├─> Validating ──valid──> Transforming
                  ├─> Transforming ──done──> Saving
                  └─> Saving

All processing sub-states can transition to Failed, TimedOut, or Cancelled without duplicating transitions.

Nested Super States

Super states can contain other super states (multiple levels of nesting):

Main Process (Super State)
  │
  ├─> Preparation (Super State)
  │     ├─> Planning
  │     └─> Setup
  │
  └─> Execution (Super State)
        ├─> Running
        └─> Monitoring

Best Practice: Limit nesting to 2-3 levels for maintainability.

History States

History states remember which sub-state was active when exiting a super state, allowing the workflow to resume at that exact sub-state on re-entry.

Concept

Without history states, re-entering a super state always starts at the default sub-state. With history states, the workflow remembers and resumes the previous sub-state.

Use cases: - Pause and resume workflows - Temporary interruptions (no-pay leave, system maintenance) - Returning to previous context after detour

Types of History

Shallow History: - Remembers immediate sub-state only - Does not remember nested sub-states within sub-states

Deep History: - Remembers entire state hierarchy - Ambience workflows use shallow history

Example: Employee Status Workflow

Without History State:

Confirmed (Super State)
  ├─> Grade1 ──promote──> Grade2
  └─> Grade2 ──promote──> Grade3

Confirmed ──no_pay_leave──> NoPay
NoPay ──return──> Confirmed (always enters Grade1)

Problem: Employee in Grade2 takes no-pay leave. On return, they’re placed in Grade1 (incorrect).

With History State:

Confirmed (Super State)
  ├─> Grade1 ──promote──> Grade2
  ├─> Grade2 ──promote──> Grade3
  └─> CurrentGrade (History State)

Confirmed ──no_pay_leave──> NoPay
NoPay ──return──> CurrentGrade (remembers Grade2)

Solution: History state remembers Grade2, employee returns to correct grade.

Creating History States

In the Workflow Designer:

  1. Create a state within the super state
  2. Set History property to checked
  3. Name it descriptively (e.g., “CurrentGrade”, “LastPosition”)
  4. Create transitions that target the history state

Visual Indicator: History states show a two-bar icon (⊏⊐) in the upper right corner.

Configuration

History State Properties: - Label: “CurrentGrade” - Super State: “Confirmed” (must be within a super state) - History: Checked - OnEntry: Optional chain to execute on resume - OnExit: Optional chain to execute on pause

Behavior

On Exit from Super State: - History state records current sub-state - Stored in workflow instance state

On Entry to History State: - Workflow transitions to remembered sub-state - If no history (first entry), goes to default sub-state

Advanced Pattern: Multi-Level Pause/Resume

Active Work (Super State)
  ├─> Phase1 (Super State)
  │     ├─> Step1A
  │     ├─> Step1B
  │     └─> Phase1History (History)
  │
  ├─> Phase2 (Super State)
  │     ├─> Step2A
  │     ├─> Step2B
  │     └─> Phase2History (History)
  │
  └─> WorkHistory (History)

Active Work ──pause──> Paused
Paused ──resume──> WorkHistory

This allows pausing at any level and resuming exactly where left off.

Deferred Events

Deferred events (configured via OnAfter property) schedule events to fire at a future time, enabling timeouts, reminders, and escalations.

Concept

OnAfter schedules an event to be sent to the workflow instance after a specified time delay. The event is managed by the Agenda system and fires automatically.

Common uses: - Timeout handling (auto-reject after 7 days) - Reminder notifications (remind after 3 days) - Escalation (escalate to manager after 2 days) - Auto-approval (approve if no response in 5 days) - SLA monitoring (warn at 80% of deadline)

Configuration

OnAfter Property (on any state): - Units: Days, Hours, or Minutes - Time: Numeric value (e.g., 3) - Event: Event name to fire (e.g., “timeout”)

Example: - Units: Days - Time: 3 - Event: escalate

Result: 3 days after entering this state, “escalate” event is sent to the instance.

Creating Deferred Event Handlers

  1. Configure OnAfter on the state
  2. Create a transition that responds to the deferred event
  3. Implement the transition’s OnTransition chain

Example: Escalation After 3 Days

State: “Pending Approval” - OnAfter: - Units: Days - Time: 3 - Event: escalate

Transition: “escalate” (Pending Approval → Pending Approval, loop) - Event: escalate - OnTransition: SendEscalationEmail chain

Multiple Deferred Events

A state can have only one OnAfter configuration, but you can chain deferred events:

Example: Progressive Escalation

State: “Pending Approval” - OnAfter: 2 days → “warn”

Transition: “warn” (loop back to Pending Approval) - Event: warn - OnTransition: Send warning email - Updates state data: escalationLevel = 1

State: “Pending Approval” (after warning) - OnAfter: 2 days → “escalate” - (Conditional based on escalationLevel)

Transition: “escalate” (loop or move to higher approval) - Event: escalate - OnTransition: Send escalation email or auto-approve

Canceling Deferred Events

Deferred events are automatically cancelled when: - The workflow transitions to a different state - The workflow reaches Stop state - The workflow instance is deleted

Example: - State “Pending Approval” has OnAfter: 3 days → “timeout” - If approved after 1 day, transition to “Approved” state - The “timeout” event is automatically cancelled

Advanced Pattern: SLA Monitoring

In Progress State:
- OnAfter: 80% of SLA time → "sla_warning"

Transition: sla_warning (loop)
- Event: sla_warning
- OnTransition: 
  - Send warning email
  - Update elxPublic.slaStatus = "Warning"
  - Schedule next check

In Progress State (after warning):
- OnAfter: Remaining 20% of SLA time → "sla_breach"

Transition: sla_breach
- Event: sla_breach
- OnTransition:
  - Send breach notification
  - Create escalation ticket
  - Update elxPublic.slaStatus = "Breached"

Time Calculations

Units: - Minutes: Exact minutes (e.g., 30 = 30 minutes) - Hours: Converted to minutes (e.g., 2 hours = 120 minutes) - Days: Converted to minutes (e.g., 1 day = 1440 minutes)

Scheduling: - Events scheduled via Agenda system - Minimum delay: 1 minute - Maximum delay: No hard limit (practical limit ~30 days)

Important: Times are calendar time, not business hours. For business hour calculations, use ETL chains.

Multiple State Machines

A single workflow can contain multiple state machines that execute in parallel, enabling complex coordination patterns.

Concept

Each state machine in a workflow: - Maintains its own state independently - Processes the same events - Can coordinate via guards

Think of it like: - Multiple threads in a program - Parallel processes in a business - Independent but coordinated activities

When to Use Multiple State Machines

Use multiple state machines when: - Modeling parallel independent processes - Separating concerns (main flow + audit, main flow + SLA tracking) - Different aspects of same process have different lifecycles - Need coordination between parallel activities

Example scenarios: - Order processing + Payment processing (parallel) - Main workflow + SLA monitoring - Document approval + Version control - Issue resolution + Customer communication

Creating Multiple State Machines

In the Workflow Designer:

  1. Click “More Actions” (three bars icon)
  2. Select “Add”
  3. Enter name for new state machine
  4. Set initial zoom level
  5. Design the new state machine

Navigation: - Tabs at top show all state machines - Click tab to switch between state machines - Each has independent states and transitions

Example: Issue Tracking with SLA

State Machine 1: Issue Lifecycle

Start → New → Open → In Progress → Resolved → Closed → Stop

State Machine 2: SLA Tracker

Start → On Time → Warning → Overdue → Stop

Coordination: - Both process same events - SLA Tracker monitors time independently - Guards can check SLA state before allowing actions

Event Processing

When an event is sent to a workflow instance:

  1. Event delivered to ALL state machines
  2. Each state machine evaluates its transitions
  3. Matching transitions fire in each state machine
  4. All state machines update independently

Example:

Event: “resolve” - Issue Lifecycle: In Progress → Resolved - SLA Tracker: Any state → Stop (via guard checking if resolved)

State Machine Coordination

Use guards to coordinate between state machines:

Guard Type: State Machine Guard - Checks if another state machine is in specific state - Transition fires only if condition met

Example: Prevent Closing if SLA Breached

Transition: “close” (Resolved → Closed) - Guard: State Machine Guard - State Machine: SLA Tracker - State: Not “Overdue” - Result: Can only close if SLA not breached

Advanced Pattern: Approval + Notification

State Machine 1: Approval Flow

Draft → Pending → Approved → Completed

State Machine 2: Notification Flow

Start → Notifying → Notified → Stop

Coordination: - When Approval Flow enters “Pending”, Notification Flow sends email - When Approval Flow enters “Approved”, Notification Flow sends confirmation - Notification Flow tracks notification status independently

Best Practices

Keep State Machines Focused: - Each state machine should have single responsibility - Don’t create too many (2-4 is typical, >5 is complex) - Name descriptively (MainFlow, SLATracker, AuditTrail)

Minimize Coupling: - State machines should be mostly independent - Use guards for necessary coordination - Avoid tight dependencies

Consider Performance: - More state machines = more processing per event - Keep state machines simple - Use guards efficiently

Guard Conditions

Guards are conditions that must be true for a transition to fire. They enable conditional logic in workflows.

Types of Guards

1. ETL Chain Guard

Execute an ETL chain to evaluate condition.

Configuration: - Guard: Chain - Name: Select ETL chain (e.g., “CheckApprovalRules”)

Behavior: - Chain executes when event matches transition - If chain succeeds: Transition fires - If chain fails: Transition blocked, try next transition

Requirements: - Chain must include workflow.GuardEndPoint step - Chain should be pure evaluation (no side effects) - Return success/failure based on condition

Example Chain: CheckApprovalRules

1. GetCurrentState
2. Transform: Extract amount
3. Conditional: Check if user has authority for amount
4. workflow.GuardEndPoint

2. State Machine Guard

Check if another state machine is in specific state.

Configuration: - Guard: State Machine - Name: Select state machine - State: Select required state

Behavior: - Checks specified state machine’s current state - If in required state: Transition fires - If not in required state: Transition blocked

Example:

Transition: “close” - Guard: State Machine - Name: SLA Tracker - State: On Time - Result: Can only close if SLA is on time

Guard Evaluation Order

When event arrives:

  1. Find all transitions from current state matching event name
  2. Evaluate guards in order (top to bottom in designer)
  3. First transition with passing guard fires
  4. Remaining transitions ignored

Important: Order matters! Place more specific guards first.

Multiple Guards Pattern

Use multiple transitions with different guards for conditional routing:

Example: Route by Amount

Transition 1: “submit” → “Senior Approval” - Event: submit - Guard: Amount > $10,000

Transition 2: “submit” → “Manager Approval” - Event: submit - Guard: Amount <= $10,000

Result: High-value requests go to senior approval, others to manager.

Guard Best Practices

Keep Guards Pure: - No data modifications - No external system updates - Fast execution - Deterministic results

Handle Guard Failures: - Provide fallback transitions - Log guard failures for debugging - Consider default transition with no guard

Test Guards Thoroughly: - Test all conditions - Test edge cases - Test guard order dependencies

Loop Transitions

Loop transitions have the same source and target state, enabling re-processing and retry logic.

Use Cases

Common uses: - Retry failed operations - Escalation (stay in state, send notification) - Periodic checks - Incremental processing - State refresh

Creating Loop Transitions

In the Workflow Designer:

  1. Select source state
  2. Click “Create Transition”
  3. Click same state as target
  4. Configure transition properties

Visual: Loop transitions appear as curved arrows from state back to itself.

Example: Escalation Loop

State: “Pending Approval”

Transition: “escalate” (Pending Approval → Pending Approval) - Event: escalate - OnTransition: SendEscalationEmail - Updates escalation counter

OnAfter: 2 days → “escalate”

Result: Every 2 days, escalation email sent, stays in Pending Approval.

Example: Retry Loop

State: “Processing”

Transition: “retry” (Processing → Processing) - Event: retry - Guard: Check retry count < 3 - OnTransition: Increment retry count, retry operation

OnAfter: 5 minutes → “retry”

Result: Retries operation every 5 minutes, up to 3 times.

Loop with State Changes

Loop transitions can modify state data:

Example: Progressive Timeout

OnTransition chain for loop:
1. GetCurrentState
2. Transform: Get timeout count
3. Transform: Increment count
4. workflow.MergeToElxPrivate: Update count
5. Conditional: If count >= 3, auto-approve

Best Practices

Prevent Infinite Loops: - Always have exit condition (guard or counter) - Set maximum iterations - Provide manual override

Monitor Loop Execution: - Log each loop iteration - Track loop counters in state data - Alert on excessive looping

Consider Performance: - Avoid tight loops (use OnAfter for delays) - Limit loop iterations - Clean up loop data after exit

See Also