Advanced Features
This section covers advanced workflow features for complex business process modeling.
Table of Contents
- Super States
- History States
- Deferred Events
- Multiple State Machines
- Guard Conditions
- Loop Transitions
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:
- Create the super state (e.g., “InProgress”)
- Create sub-states (e.g., “Filling”, “Capping”, “Labeling”)
- For each sub-state, set Super State property to the super state
- Add transitions to the super state (these are inherited by all sub-states)
- 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:
- Create a state within the super state
- Set History property to checked
- Name it descriptively (e.g., “CurrentGrade”, “LastPosition”)
- 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
- Configure OnAfter on the state
- Create a transition that responds to the deferred event
- 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:
- Click “More Actions” (three bars icon)
- Select “Add”
- Enter name for new state machine
- Set initial zoom level
- 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:
- Event delivered to ALL state machines
- Each state machine evaluates its transitions
- Matching transitions fire in each state machine
- 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:
- Find all transitions from current state matching event name
- Evaluate guards in order (top to bottom in designer)
- First transition with passing guard fires
- 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:
- Select source state
- Click “Create Transition”
- Click same state as target
- 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
- Core Concepts - Fundamental workflow concepts
- Workflow Designer - Designing workflows
- Examples - Real-world examples
- Best Practices - Design patterns and guidelines