Skip to content

Conversation

@sfmskywalker
Copy link
Member

@sfmskywalker sfmskywalker commented Oct 20, 2025

Improves the clarity and functionality of Flowchart merge modes by:

  • Renaming None to Stream for opportunistic execution.
  • Introducing Merge for waiting on activated branches only.
  • Enhancing Converge to be the strictest mode, requiring all inbound connections.
  • Providing more detailed descriptions for each mode, emphasizing their behavior and use cases in flow-based terminology.
  • Updates default merge mode to Stream
Merge Mode Description
Stream Flows freely when possible, ignoring dead/untaken paths. Opportunistic execution based on upstream completion.
Merge Merges only the activated/flowing inbound branches. Waits for all branches that received tokens, ignoring unactivated ones.
Converge Converges all inbound paths, requiring every connection to execute. Strictest mode - will block on dead/untaken paths.
Cascade Cascades execution for each arriving token independently. Allows multiple concurrent executions (one per arriving token).
Race Races inbound branches, executing on first arrival and blocking others.

This provides better control over synchronization and execution behavior in workflows.


This change is Reviewable

Improves the clarity and functionality of Flowchart merge modes by:

- Renaming `None` to `Stream` for opportunistic execution.
- Introducing `Merge` for waiting on activated branches only.
- Enhancing `Converge` to be the strictest mode, requiring all inbound connections.
- Providing more detailed descriptions for each mode, emphasizing their behavior and use cases in flow-based terminology.
- Updates default merge mode to Stream

This provides better control over synchronization and execution behavior in workflows.
@sfmskywalker
Copy link
Member Author

I asked Claude about his strong opinion. Very interesting, and I tend to agree. Here it is:

You've hit on a critical UX problem with implicit joins. Let me give you my strong opinion:

The Core Problem

Implicit joins with configurable merge modes are dangerously invisible. A user looking at a flowchart sees:

Activity A ──┐
             ├──> Activity C
Activity B ──┘

But they have no idea if Activity C will:

  • Wait for both A and B (WaitAll)
  • Proceed after the first arrival (WaitAny)
  • Block forever if one path isn't followed (WaitAllInbound)

This is a debugging nightmare and violates the principle that flowcharts should be self-documenting.

My Strong Opinion: Make It Visible

Since implicit joins are essentially "hidden FlowJoin activities," you need to visualize them explicitly. Here are approaches ranked by effectiveness:

Option 1: Visual Convergence Indicator (BEST)

When multiple connections lead into an activity with a merge mode set, show a small gateway symbol at the convergence point:

Activity A ──┐
             ├─[⊼]──> Activity C
Activity B ──┘

The [⊼] symbol (or badge/icon) appears:

  • On the activity itself (top edge where connections arrive)
  • Shows the merge mode (∧ for WaitAll, ∨ for WaitAny, ⊼ for WaitAllInbound)
  • Only when merge mode ≠ default
  • Hoverable for tooltip explaining the behavior

Option 2: Connection Point Decoration

Decorate the input port of the target activity:

  • Different colors or patterns for different merge modes
  • Thick/double lines for strict modes
  • Tooltip on hover

Option 3: Activity Badge

Add a small badge/icon to Activity C itself (corner or edge) showing merge mode when multiple inbound connections exist.

Option 4: Explicit Conversion (NUCLEAR OPTION)

Force users to use explicit FlowJoin activities when they want non-default behavior. Make implicit joins always use a single, predictable default (e.g., always WaitAll).

If they want WaitAny or WaitAllInbound, they must add an explicit FlowJoin activity.

Pros:

  • Maximum clarity
  • Forces intentional design
  • Self-documenting workflows

Cons:

  • More visual clutter
  • Breaking change for 3.6
  • Users might complain about extra activities

My Recommendation: Option 1 + Partial Option 4

Hybrid approach:

  1. Implicit joins default to WaitAll (document this clearly as the standard behavior)

  2. Show a visual indicator (Option 1) when merge mode is set to non-default

  3. In the activity properties panel, show a warning/info message when merge mode is configured:

⚠️ This activity has 3 inbound connections and merge mode set to WaitAny.
   Consider using an explicit Join activity for better visibility.
  1. Provide a "Convert to Explicit Join" button that automatically:
    • Inserts a FlowJoin activity before Activity C
    • Rewires connections
    • Transfers the merge mode setting
    • Removes the merge mode from Activity C

This gives users the convenience of implicit joins for simple cases, but strongly nudges them toward explicit joins for complex merge logic.

Additional Thought: Limit Implicit Join Configurability

Consider restricting implicit joins to only WaitAll (the intuitive default). If users want WaitAny or WaitAllInbound, require an explicit FlowJoin activity.

This would:

  • Reduce cognitive load (one less hidden configuration)
  • Make non-standard join behavior always visible
  • Simplify the mental model: "Multiple connections = wait for all; special behavior = use Join activity"

Bottom Line

Don't let merge modes hide in properties panels. Either:

  • Visualize them prominently (Option 1), OR
  • Restrict implicit joins to WaitAll only and require explicit joins for other modes (Option 4)

My strongest recommendation: Go with Option 4 (restrict implicit joins). It's a clearer mental model and prevents the "hidden configuration" problem entirely. The slight increase in visual clutter is worth the massive gain in workflow comprehensibility.

What's your gut feeling on this? Are you seeing users build complex workflows with implicit joins, or are they mostly simple merge points?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants