# Concurrent Region

Like [Nested States](/states/nested-states.md), concurrent regions are designed to control the combinatorial explosions that can occur in an FSM.

{% hint style="info" %}
UML2 refers to Concurrent Regions as 'orthogonal regions' meaning independant regions. Concurrent Region seems more descriptive hence our naming choice.
{% endhint %}

Concurrent regions allow you to have two or more concurrently active states within your state machine.

FSM2 uses the 'coregion' builder to create a concurrent region.

```dart
  machine = StateMachine.create((g) => g
    ..initialState<MaintainAir>()
    ..state<MaintainAir>((b) => b
      ..state<MonitorAir>((b) => b
        ..onFork<OnBadAir>((b) => b
          ..target<HandleFan>()
          ..target<HandleLamp>()
          ..target<WaitForGoodAir>(),
            condition: (s, e) => e.quality < 10))
      ..coregion<CleanAir>((b) => b
        ..state<HandleFan>((b) => b
          ..onEnter((s, e) async => turnFanOn())
          ..onExit((s, e) async => turnFanOff())
          ..onJoin<OnFanRunning, MonitorAir>(condition: ((e) => e.speed > 5))
          ..state<FanOff>((b) => b)
          ..state<FanOn>((b) => b
            ..onEnter((s, e) async => machine.applyEvent(OnFanRunning()))))
        ..state<HandleLamp>((b) => b
          ..onEnter((s, e) async =>  turnLightOn(machine))
          ..onExit((s, e) async =>  turnLightOff(machine))
          ..onJoin<OnLampOn, MonitorAir>()
          ..state<LampOff>((b) => b)
          ..state<LampOn>((b) => b
            ..onEnter((s, e) async => machine.applyEvent(OnLampOn()))))
        ..state<WaitForGoodAir>((b) => b..onJoin<OnGoodAir, MonitorAir>())))
    ..onTransition((s, e, st) {}));
```

In the above FSM the  'CleanAir' is  denoted as a concurrent region via the 'coregion' builder.

Each of 'CleanAir's immediate child states  'HandleFan' and 'HandleLamp' are concurrent states. The FSM can be in both of these states at the same time.

The concurrency of this example makes sense in the real world if you consider that the state of the fan (on/off) is completely independent of the state of the lamp.

If we look at the 'HandleFan' state we see that it has to child states 'FanOff' and 'FanOn'. These are normal nested states and whilst in the 'HandleFan'  state we can expect to move between the 'FanOff' and 'FanOn' states.

If you have only used a simple FSM then you may think of an FSM as only being in a single state. With UML2 and FSM2 concurrent regions and nested states create additional states that your FSM can be in simultaneously.

* Each immediate children of a concurrent region are considered completely independant. There is no limit on the no. of concurrent regions that an FSM may have nor the no. of immediate children.
* Concurrent regions can be nested within other states and you can nest states within a concurrent region.
* You enter a concurrent region using the [onFork](/states/concurrent-states/fork.md) pseudo state which FSM2 models as a transition with multiple target states. This would normally be each of the immediate children.&#x20;
* You exit a concurrent region using either the [onJoin](/states/concurrent-states/join.md) pseudo state or a simple '[on](/transitions/static-transitions.md)' transition.
* When you enter a co-region then you enter EVERY substate.
* If you use an 'on' transition or an 'onFork' that doesn't explicitly target every sub state then for all other substates their 'initialState' is entered.
* If a transition causes any state to transition to a start external to the co-region then all of the co-region's substates are exited.
* Once in a concurrent region, transitions between child states can occur independently of each other.

if you have [concurrent regions](/states/concurrent-states.md) in you FSM and a concurrent region is active when an event is applied, only one of the active states needs to be able to handle the event.&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fsm2.onepub.dev/states/concurrent-states.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
