effect-tsでRequirements Managementでabort対応

前回の処理を1段階複雑にした場合の処理のメモ

* MainRuntime は 通常処理
* TestRuntime は 高速処理
* NoneLogRuntime は 通常処理をモックデータ利用でログ出力なし
    * ログ出力しないため一部省略

# 前回

https://qiita.com/kuangzhixitian3/items/b22f0df49b21c2f1814d

## 配列が１つの場合

### 全部同時実行

```plantuml
@startuml
robust "全体" as all
concise "https://test/1" as test1
compact concise "abort" as test1c
concise "https://test/2" as test2
compact concise "abort" as test2c
concise "https://test/3" as test3
concise "https://test/4" as test4
compact concise "abort" as test4c
concise "https://test/5" as test5
compact concise "abort" as test5c
concise "https://test/10" as test10

@all
0 is 待機中
+1 is 処理中
+0.01 is 中断中

@1
test1 -> test1c 
test2 -> test2c
test4 -> test4c
test5 -> test5c

@test1
1 is 処理中
+1 is {hidden}
@test1c
1 is aborted #gray
+0.01 is {hidden}

@test2
1 is 処理中 #pink
+2 is {hidden}
@test2c
1 is aborted #gray
+0.01 is {hidden}

@test3
1 is 処理中 #pink
+0.01 is {hidden}

@test4
1 is 処理中 #pink
+4 is {hidden}
@test4c
1 is aborted #gray
+0.01 is {hidden}

@test5
1 is 処理中
+5 is {hidden}
@test5c
1 is aborted #gray
+0.01 is {hidden}

@test10
1 is abort #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T10:59:56.223Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T10:59:56.247Z level=INFO fiber=#15 message="[sites] : https://main/1,https://main/2,https://main/3,https://main/4,https://main/5,https://main/10"
timestamp=2025-03-18T10:59:56.250Z level=INFO fiber=#23 message="https://main/10 - abort - lastIndex >= 10"
timestamp=2025-03-18T10:59:56.251Z level=INFO fiber=#24 message="https://main/1 - aborted - from event"
timestamp=2025-03-18T10:59:56.251Z level=INFO fiber=#25 message="https://main/2 - aborted - from event"
timestamp=2025-03-18T10:59:56.252Z level=INFO fiber=#26 message="https://main/3 - aborted - from event"
timestamp=2025-03-18T10:59:56.252Z level=INFO fiber=#27 message="https://main/4 - aborted - from event"
timestamp=2025-03-18T10:59:56.252Z level=INFO fiber=#28 message="https://main/5 - aborted - from event"
timestamp=2025-03-18T10:59:56.259Z level=INFO fiber=#29 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:00:56.862Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:00:56.892Z level=INFO fiber=#15 message="[sites] : https://main/1,https://main/2,https://main/3,https://main/4,https://main/5"
timestamp=2025-03-18T11:00:56.899Z level=INFO fiber=#20 message="https://main/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:00:57.912Z level=INFO fiber=#18 message="https://main/1 - ok - 1000"
timestamp=2025-03-18T11:00:58.908Z level=INFO fiber=#19 message="https://main/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:01:00.901Z level=INFO fiber=#21 message="https://main/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:01:01.913Z level=INFO fiber=#22 message="https://main/5 - ok - 5000"
timestamp=2025-03-18T11:01:01.915Z level=INFO fiber=#23 message="[
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 1000
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 2000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"_tag\": \"SleepNGBeforeError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 4000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 5000
    }
  }
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:01:50.024Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:01:50.055Z level=INFO fiber=#18 message="[sites] : https://test/1,https://test/2,https://test/3,https://test/4,https://test/5,https://test/10"
timestamp=2025-03-18T11:01:50.060Z level=INFO fiber=#23 message="https://test/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:01:50.061Z level=INFO fiber=#26 message="https://test/10 - abort - lastIndex >= 10"
timestamp=2025-03-18T11:01:50.062Z level=INFO fiber=#27 message="https://test/1 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:01:50.062Z level=INFO fiber=#28 message="https://test/2 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:01:50.063Z level=INFO fiber=#29 message="https://test/4 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:01:50.063Z level=INFO fiber=#30 message="https://test/5 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:01:50.069Z level=INFO fiber=#31 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:02:42.731Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:02:42.763Z level=INFO fiber=#18 message="[sites] : https://test/1,https://test/2,https://test/3,https://test/4,https://test/5"
timestamp=2025-03-18T11:02:42.774Z level=INFO fiber=#23 message="https://test/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:02:43.275Z level=INFO fiber=#21 message="https://test/1 - ok - 1000"
timestamp=2025-03-18T11:02:43.772Z level=INFO fiber=#22 message="https://test/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:02:44.790Z level=INFO fiber=#24 message="https://test/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:02:45.286Z level=INFO fiber=#25 message="https://test/5 - ok - 5000"
timestamp=2025-03-18T11:02:45.291Z level=INFO fiber=#26 message="[
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 1000
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 2000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"_tag\": \"SleepNGBeforeError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 4000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 5000
    }
  }
]"
```

#### NoneLogRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:05:23.081Z level=INFO fiber=#3 message=[start]
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:05:53.614Z level=INFO fiber=#3 message=[start]
```


### 最大２個まで同時実行

```plantuml
@startuml
robust "全体" as all
concise "https://test/1" as test1
concise "https://test/2" as test2
concise "https://test/3" as test3
concise "https://test/4" as test4
concise "https://test/5" as test5
compact concise "abort" as test5c
concise "https://test/10" as test10

@all
0 is 待機中
+1 is 処理中
+5 is 中断中

@6
test5 -> test5c

@test1
1 is 処理中
+1 is {hidden}

@test2
1 is 処理中 #pink
+2 is {hidden}

@test3
2 is 処理中 #pink
+0.01 is {hidden}

@test4
2 is 処理中 #pink
+4 is {hidden}

@test5
3 is 処理中
+5 is {hidden}
@test5c
6 is aborted #gray
+0.01 is {hidden}

@test10
6 is abort #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:10:40.342Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:10:40.370Z level=INFO fiber=#15 message="[sites] : https://main/1,https://main/2,https://main/3,https://main/4,https://main/5,https://main/10"
timestamp=2025-03-18T11:10:41.384Z level=INFO fiber=#18 message="https://main/1 - ok - 1000"
timestamp=2025-03-18T11:10:41.398Z level=INFO fiber=#18 message="https://main/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:10:42.378Z level=INFO fiber=#19 message="https://main/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:10:45.406Z level=INFO fiber=#18 message="https://main/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:10:45.407Z level=INFO fiber=#18 message="https://main/10 - abort - lastIndex >= 10"
timestamp=2025-03-18T11:10:45.408Z level=INFO fiber=#20 message="https://main/5 - aborted - from event"
timestamp=2025-03-18T11:10:45.413Z level=INFO fiber=#21 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:12:45.418Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:12:45.444Z level=INFO fiber=#15 message="[sites] : https://main/1,https://main/2,https://main/3,https://main/4,https://main/5"
timestamp=2025-03-18T11:12:46.460Z level=INFO fiber=#18 message="https://main/1 - ok - 1000"
timestamp=2025-03-18T11:12:46.464Z level=INFO fiber=#18 message="https://main/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:12:47.461Z level=INFO fiber=#19 message="https://main/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:12:50.480Z level=INFO fiber=#18 message="https://main/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:12:52.470Z level=INFO fiber=#19 message="https://main/5 - ok - 5000"
timestamp=2025-03-18T11:12:52.471Z level=INFO fiber=#20 message="[
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 1000
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 2000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"_tag\": \"SleepNGBeforeError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 4000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 5000
    }
  }
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:14:05.744Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:14:05.773Z level=INFO fiber=#18 message="[sites] : https://test/1,https://test/2,https://test/3,https://test/4,https://test/5,https://test/10"
timestamp=2025-03-18T11:14:06.285Z level=INFO fiber=#21 message="https://test/1 - ok - 1000"
timestamp=2025-03-18T11:14:06.289Z level=INFO fiber=#21 message="https://test/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:14:06.796Z level=INFO fiber=#22 message="https://test/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:14:08.293Z level=INFO fiber=#21 message="https://test/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:14:08.294Z level=INFO fiber=#21 message="https://test/10 - abort - lastIndex >= 10"
timestamp=2025-03-18T11:14:08.297Z level=INFO fiber=#23 message="https://test/5 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:14:08.302Z level=INFO fiber=#24 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:14:56.170Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:14:56.200Z level=INFO fiber=#18 message="[sites] : https://test/1,https://test/2,https://test/3,https://test/4,https://test/5"
timestamp=2025-03-18T11:14:56.716Z level=INFO fiber=#21 message="https://test/1 - ok - 1000"
timestamp=2025-03-18T11:14:56.718Z level=INFO fiber=#21 message="https://test/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T11:14:57.215Z level=INFO fiber=#22 message="https://test/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:14:58.723Z level=INFO fiber=#21 message="https://test/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T11:14:59.720Z level=INFO fiber=#22 message="https://test/5 - ok - 5000"
timestamp=2025-03-18T11:14:59.721Z level=INFO fiber=#23 message="[
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 1000
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 2000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"_tag\": \"SleepNGBeforeError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Left\",
    \"left\": {
      \"wait\": 4000,
      \"_tag\": \"SleepNGAfterError\"
    }
  },
  {
    \"_id\": \"Either\",
    \"_tag\": \"Right\",
    \"right\": {
      \"wait\": 5000
    }
  }
]"
```

#### NoneLogRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:15:25.003Z level=INFO fiber=#3 message=[start]
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:15:50.145Z level=INFO fiber=#3 message=[start]
```



## 配列が２つの場合（シンプル）

### 全部同時実行からの全部同時実行

```plantuml
@startuml
robust "全体" as all
concise "https://test/7" as test7
concise "https://test/7/1" as test7_1
compact concise "abort" as test71c
concise "https://test/7/2" as test7_2
compact concise "abort" as test72c
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
compact concise "abort" as test74c
concise "https://test/7/5" as test7_5
compact concise "abort" as test75c
concise "https://test/7/6" as test7_6
compact concise "abort" as test76c
concise "https://test/7/7" as test7_7
compact concise "abort" as test77c

@all
0 is 待機中
+1 is 処理中
+7 is 中断中

@8
test7_1 -> test71c
test7_2 -> test72c
test7_4 -> test74c
test7_5 -> test75c
test7_6 -> test76c
test7_7 -> test77c

@test7
1 is 処理中
+7 is {hidden}

@test7_1
8 is 処理中
+1 is {hidden}
@test71c
8 is aborted #gray
+0.01 is {hidden}

@test7_2
8 is 処理中 #pink
+2 is {hidden}
@test72c
8 is aborted #gray
+0.01 is {hidden}

@test7_3
8 is abort #gray
+0.01 is {hidden}

@test7_4
8 is abort #gray
+0.01 is {hidden}
@test74c
8 is aborted #gray
+0.01 is {hidden}

@test7_5
8 is abort #gray
+0.01 is {hidden}
@test75c
8 is aborted #gray
+0.01 is {hidden}

@test7_6
8 is abort #gray
+0.01 is {hidden}
@test76c
8 is aborted #gray
+0.01 is {hidden}

@test7_7
8 is abort #gray
+0.01 is {hidden}
@test77c
8 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:17:39.511Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:17:39.541Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T11:17:46.557Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:17:46.564Z level=INFO fiber=#22 message="https://main/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:17:46.567Z level=INFO fiber=#27 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:17:46.569Z level=INFO fiber=#28 message="https://main/7/1 - aborted - from event"
timestamp=2025-03-18T11:17:46.569Z level=INFO fiber=#29 message="https://main/7/2 - aborted - from event"
timestamp=2025-03-18T11:17:46.584Z level=INFO fiber=#30 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:18:45.003Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:18:45.034Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2"
timestamp=2025-03-18T11:18:52.055Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:18:53.075Z level=INFO fiber=#20 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T11:18:54.082Z level=INFO fiber=#21 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:18:54.091Z level=INFO fiber=#22 message="[
  \"https://main/7 - ok - 9000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:21:29.930Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:21:29.957Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T11:21:36.967Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:21:36.974Z level=INFO fiber=#25 message="https://test/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:21:36.977Z level=INFO fiber=#30 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:21:36.978Z level=INFO fiber=#31 message="https://test/7/1 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:21:36.979Z level=INFO fiber=#32 message="https://test/7/2 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:21:36.992Z level=INFO fiber=#33 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:22:46.097Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:22:46.130Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2"
timestamp=2025-03-18T11:22:53.143Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:22:53.652Z level=INFO fiber=#23 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T11:22:54.154Z level=INFO fiber=#24 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:22:54.158Z level=INFO fiber=#25 message="[
  \"https://test/7 - ok - 9000\"
]"
```



### 全部同時実行からの直列実行

```plantuml
@startuml
robust "全体" as all
concise "https://test/7" as test7
concise "https://test/7/1" as test7_1
concise "https://test/7/2" as test7_2
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
compact concise "abort" as test74c
concise "https://test/7/5" as test7_5
compact concise "abort" as test75c
concise "https://test/7/6" as test7_6
compact concise "abort" as test76c
concise "https://test/7/7" as test7_7
compact concise "abort" as test77c

@11
test7_4 -> test74c
test7_5 -> test75c
test7_6 -> test76c
test7_7 -> test77c

@all
0 is 待機中
+1 is 処理中
+10 is 中断中

@test7
1 is 処理中
+7 is {hidden}

@test7_1
8 is 処理中
+1 is {hidden}

@test7_2
9 is 処理中 #pink
+2 is {hidden}

@test7_3
11 is abort #gray
+0.01 is {hidden}

@test7_4
11 is abort #gray
+0.01 is {hidden}
@test74c
11 is aborted #gray
+0.01 is {hidden}

@test7_5
11 is abort #gray
+0.01 is {hidden}
@test75c
11 is aborted #gray
+0.01 is {hidden}

@test7_6
11 is abort #gray
+0.01 is {hidden}
@test76c
11 is aborted #gray
+0.01 is {hidden}

@test7_7
11 is abort #gray
+0.01 is {hidden}
@test77c
11 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:27:43.483Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:27:43.514Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T11:27:50.527Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:27:51.538Z level=INFO fiber=#18 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T11:27:53.543Z level=INFO fiber=#18 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:27:53.545Z level=INFO fiber=#18 message="https://main/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:27:53.546Z level=INFO fiber=#19 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:27:53.548Z level=INFO fiber=#20 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:27:02.317Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:27:02.347Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2"
timestamp=2025-03-18T11:27:09.363Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:27:10.379Z level=INFO fiber=#18 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T11:27:12.385Z level=INFO fiber=#18 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:27:12.386Z level=INFO fiber=#19 message="[
  \"https://main/7 - ok - 10000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:30:37.206Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:30:37.237Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T11:30:44.250Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:30:44.770Z level=INFO fiber=#21 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T11:30:45.787Z level=INFO fiber=#21 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:30:45.790Z level=INFO fiber=#21 message="https://test/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:30:45.796Z level=INFO fiber=#22 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:30:45.808Z level=INFO fiber=#23 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:29:31.011Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:29:31.040Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2"
timestamp=2025-03-18T11:29:38.060Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:29:38.572Z level=INFO fiber=#21 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T11:29:39.592Z level=INFO fiber=#21 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:29:39.596Z level=INFO fiber=#22 message="[
  \"https://test/7 - ok - 10000\"
]"
```



### 全部同時実行からの最大２個まで同時実行

```plantuml
@startuml
robust "全体" as all
concise "https://test/7" as test7
concise "https://test/7/1" as test7_1
concise "https://test/7/2" as test7_2
compact concise "abort" as test72c
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
compact concise "abort" as test74c
concise "https://test/7/5" as test7_5
compact concise "abort" as test75c
concise "https://test/7/6" as test7_6
compact concise "abort" as test76c
concise "https://test/7/7" as test7_7
compact concise "abort" as test77c

@9
test7_2 -> test72c
test7_4 -> test74c
test7_5 -> test75c
test7_6 -> test76c
test7_7 -> test77c

@all
0 is 待機中
+1 is 処理中
+8 is 中断中

@test7
1 is 処理中
+7 is {hidden}

@test7_1
8 is 処理中
+1 is {hidden}

@test7_2
8 is 処理中 #pink
+2 is {hidden}
@test72c
9 is aborted #gray
+0.01 is {hidden}

@test7_3
9 is abort #gray
+0.01 is {hidden}

@test7_4
9 is abort #gray
+0.01 is {hidden}
@test74c
9 is aborted #gray
+0.01 is {hidden}

@test7_5
9 is abort #gray
+0.01 is {hidden}
@test75c
9 is aborted #gray
+0.01 is {hidden}

@test7_6
9 is abort #gray
+0.01 is {hidden}
@test76c
9 is aborted #gray
+0.01 is {hidden}

@test7_7
9 is abort #gray
+0.01 is {hidden}
@test77c
9 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:31:04.792Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:31:04.821Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T11:31:11.832Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:31:12.845Z level=INFO fiber=#20 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T11:31:12.846Z level=INFO fiber=#20 message="https://main/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:31:12.847Z level=INFO fiber=#22 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:31:12.848Z level=INFO fiber=#23 message="https://main/7/2 - aborted - from event"
timestamp=2025-03-18T11:31:12.851Z level=INFO fiber=#24 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:32:27.394Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:32:27.422Z level=INFO fiber=#15 message="[sites] : https://main/7/1,https://main/7/2"
timestamp=2025-03-18T11:32:34.442Z level=INFO fiber=#18 message="mapper2-index = 7"
timestamp=2025-03-18T11:32:35.457Z level=INFO fiber=#20 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T11:32:36.465Z level=INFO fiber=#21 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:32:36.473Z level=INFO fiber=#22 message="[
  \"https://main/7 - ok - 9000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T11:45:06.575Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:45:06.605Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T11:45:13.624Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:45:14.137Z level=INFO fiber=#23 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T11:45:14.139Z level=INFO fiber=#23 message="https://test/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T11:45:14.140Z level=INFO fiber=#25 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T11:45:14.141Z level=INFO fiber=#26 message="https://test/7/2 - aborted - from event - test - abort_event"
timestamp=2025-03-18T11:45:14.144Z level=INFO fiber=#27 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T11:44:34.157Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T11:44:34.185Z level=INFO fiber=#18 message="[sites] : https://test/7/1,https://test/7/2"
timestamp=2025-03-18T11:44:41.206Z level=INFO fiber=#21 message="mapper2-index = 7"
timestamp=2025-03-18T11:44:41.734Z level=INFO fiber=#23 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T11:44:42.235Z level=INFO fiber=#24 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T11:44:42.239Z level=INFO fiber=#25 message="[
  \"https://test/7 - ok - 9000\"
]"
```


## 配列が２つの場合（複雑）

### 全部同時実行からの全部同時実行

```plantuml
@startuml
robust "全体" as all

concise "https://test/1" as test1
concise "https://test/1/1" as test1_1

concise "https://test/2" as test2
concise "https://test/2/1" as test2_1
concise "https://test/2/2" as test2_2

concise "https://test/3" as test3
concise "https://test/3/1" as test3_1
concise "https://test/3/2" as test3_2
concise "https://test/3/3" as test3_3

concise "https://test/4" as test4
concise "https://test/4/1" as test4_1
concise "https://test/4/2" as test4_2
concise "https://test/4/3" as test4_3
concise "https://test/4/4" as test4_4

concise "https://test/5" as test5
concise "https://test/5/1" as test5_1
compact concise "abort" as test51c
concise "https://test/5/2" as test5_2
compact concise "abort" as test52c
concise "https://test/5/3" as test5_3
concise "https://test/5/4" as test5_4
compact concise "abort" as test54c
concise "https://test/5/5" as test5_5

concise "https://test/7" as test7
compact concise "abort" as test7c
concise "https://test/7/1" as test7_1
concise "https://test/7/2" as test7_2
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
concise "https://test/7/5" as test7_5
concise "https://test/7/6" as test7_6
concise "https://test/7/7" as test7_7

@6
test5_1 -> test51c
test5_2 -> test52c
test5_4 -> test54c
test7 -> test7c

@all
0 is 待機中 
+1 is 処理中
+5 is 中断中

@test1
1 is 処理中
+1 is {hidden}
@test1_1
2 is 処理中
+1 is {hidden}

@test2
1 is 処理中 #pink
+2 is {hidden}

@test3
1 is 処理中 #pink
+0.01 is {hidden}

@test4
1 is 処理中 #pink
+4 is {hidden}

@test5
1 is 処理中
+5 is {hidden}
@test5_1
6 is 処理中
+1 is {hidden}
@test51c
6 is aborted #gray
+0.01 is {hidden}
@test5_2
6 is 処理中 #pink
+2 is {hidden}
@test52c
6 is aborted #gray
+0.01 is {hidden}
@test5_3
6 is 処理中 #pink
+0.01 is {hidden}
@test5_4
6 is 処理中 #pink
+4 is {hidden}
@test54c
6 is aborted #gray
+0.01 is {hidden}
@test5_5
6 is abort #gray
+0.01 is {hidden}

@test7
1 is 処理中
+7 is {hidden}
@test7c
6 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:29:05.211Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:29:05.243Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/5/5,https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T13:29:05.248Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:29:06.252Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:29:07.253Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:29:07.255Z level=INFO fiber=#25 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:29:09.253Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:29:10.255Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:29:10.259Z level=INFO fiber=#31 message="https://main/5/5 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:29:10.263Z level=INFO fiber=#32 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:29:10.263Z level=INFO fiber=#33 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:29:10.264Z level=INFO fiber=#34 message="https://main/5/1 - aborted - from event"
timestamp=2025-03-18T13:29:10.264Z level=INFO fiber=#35 message="https://main/5/2 - aborted - from event"
timestamp=2025-03-18T13:29:10.265Z level=INFO fiber=#36 message="https://main/5/3 - aborted - from event"
timestamp=2025-03-18T13:29:10.265Z level=INFO fiber=#37 message="https://main/5/4 - aborted - from event"
timestamp=2025-03-18T13:29:10.275Z level=INFO fiber=#38 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:37:06.731Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:37:06.757Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/7/1,https://main/7/2"
timestamp=2025-03-18T13:37:06.763Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:37:07.769Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:37:08.762Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:37:08.778Z level=INFO fiber=#25 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:37:10.776Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:37:11.762Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:37:11.766Z level=INFO fiber=#29 message="https://main/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:37:12.778Z level=INFO fiber=#27 message="https://main/5/1 - ok - 1000"
timestamp=2025-03-18T13:37:13.777Z level=INFO fiber=#23 message="mapper2-index = 7"
timestamp=2025-03-18T13:37:13.785Z level=INFO fiber=#28 message="https://main/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:37:14.792Z level=INFO fiber=#32 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T13:37:15.768Z level=INFO fiber=#30 message="https://main/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:37:15.783Z level=INFO fiber=#33 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:37:15.787Z level=INFO fiber=#34 message="[
  \"https://main/1 - ok - 2000\",
  \"https://main/2 - ng - 2000 - Sleep NG after wait\",
  \"https://main/3 - ng - Sleep NG before wait\",
  \"https://main/4 - ng - 4000 - Sleep NG after wait\",
  \"https://main/5 - ok - 9000\",
  \"https://main/7 - ok - 9000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:46:12.731Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:46:12.763Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/5/5,https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T13:46:12.770Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:46:13.769Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:46:14.277Z level=INFO fiber=#28 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:46:14.769Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:46:16.780Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:46:17.773Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:46:17.780Z level=INFO fiber=#32 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:46:17.783Z level=INFO fiber=#34 message="https://test/5/5 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:46:17.788Z level=INFO fiber=#35 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:46:17.789Z level=INFO fiber=#36 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:46:17.790Z level=INFO fiber=#37 message="https://test/5/1 - aborted - from event - test - abort_event"
timestamp=2025-03-18T13:46:17.791Z level=INFO fiber=#38 message="https://test/5/2 - aborted - from event - test - abort_event"
timestamp=2025-03-18T13:46:17.792Z level=INFO fiber=#39 message="https://test/5/4 - aborted - from event - test - abort_event"
timestamp=2025-03-18T13:46:17.804Z level=INFO fiber=#40 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:50:29.922Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:50:29.953Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/7/1,https://test/7/2"
timestamp=2025-03-18T13:50:29.958Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:50:30.973Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:50:31.487Z level=INFO fiber=#28 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:50:31.959Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:50:33.961Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:50:34.968Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:50:34.972Z level=INFO fiber=#32 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:50:35.484Z level=INFO fiber=#30 message="https://test/5/1 - ok - 1000"
timestamp=2025-03-18T13:50:35.972Z level=INFO fiber=#31 message="https://test/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:50:36.964Z level=INFO fiber=#26 message="mapper2-index = 7"
timestamp=2025-03-18T13:50:36.980Z level=INFO fiber=#33 message="https://test/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:50:37.474Z level=INFO fiber=#35 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T13:50:37.973Z level=INFO fiber=#36 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:50:37.979Z level=INFO fiber=#37 message="[
  \"https://test/1 - ok - 2000\",
  \"https://test/2 - ng - 2000 - Sleep NG after wait\",
  \"https://test/3 - ng - Sleep NG before wait\",
  \"https://test/4 - ng - 4000 - Sleep NG after wait\",
  \"https://test/5 - ok - 9000\",
  \"https://test/7 - ok - 9000\"
]"
```



### 全部同時実行からの直列実行

```plantuml
@startuml
robust "全体" as all

concise "https://test/1" as test1
concise "https://test/1/1" as test1_1

concise "https://test/2" as test2
concise "https://test/2/1" as test2_1
concise "https://test/2/2" as test2_2

concise "https://test/3" as test3
concise "https://test/3/1" as test3_1
concise "https://test/3/2" as test3_2
concise "https://test/3/3" as test3_3

concise "https://test/4" as test4
concise "https://test/4/1" as test4_1
concise "https://test/4/2" as test4_2
concise "https://test/4/3" as test4_3
concise "https://test/4/4" as test4_4

concise "https://test/5" as test5
concise "https://test/5/1" as test5_1
concise "https://test/5/2" as test5_2
concise "https://test/5/3" as test5_3
concise "https://test/5/4" as test5_4
compact concise "abort" as test54c
concise "https://test/5/5" as test5_5

concise "https://test/7" as test7
concise "https://test/7/1" as test7_1
concise "https://test/7/2" as test7_2
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
compact concise "abort" as test74c
concise "https://test/7/5" as test7_5
compact concise "abort" as test75c
concise "https://test/7/6" as test7_6
compact concise "abort" as test76c
concise "https://test/7/7" as test7_7
compact concise "abort" as test77c

@11
test5_4 -> test54c
test7_4 -> test74c
test7_5 -> test75c
test7_6 -> test76c
test7_7 -> test77c

@all
0 is 待機中
+1 is 処理中
+10 is 中断中

@test1
1 is 処理中
+1 is {hidden}
@test1_1
2 is 処理中
+1 is {hidden}

@test2
1 is 処理中 #pink
+2 is {hidden}

@test3
1 is 処理中 #pink
+0.01 is {hidden}

@test4
1 is 処理中 #pink
+4 is {hidden}

@test5
1 is 処理中
+5 is {hidden}
@test5_1
6 is 処理中
+1 is {hidden}
@test5_2
7 is 処理中 #pink
+2 is {hidden}
@test5_3
9 is 処理中 #pink
+0.01 is {hidden}
@test5_4
9 is 処理中 #pink
+4 is {hidden}
@test54c
11 is aborted #gray
+0.01 is {hidden}

@test7
1 is 処理中
+7 is {hidden}
@test7_1
8 is 処理中
+1 is {hidden}
@test7_2
9 is 処理中 #pink
+2 is {hidden}
@test7_3
11 is abort #gray
+0.01 is {hidden}
@test7_4
11 is abort #gray
+0.01 is {hidden}
@test74c
11 is aborted #gray
+0.01 is {hidden}
@test7_5
11 is abort #gray
+0.01 is {hidden}
@test75c
11 is aborted #gray
+0.01 is {hidden}
@test7_6
11 is abort #gray
+0.01 is {hidden}
@test76c
11 is aborted #gray
+0.01 is {hidden}
@test7_7
11 is abort #gray
+0.01 is {hidden}
@test77c
11 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:30:42.201Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:30:42.236Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/5/5,https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T13:30:42.243Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:30:43.251Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:30:44.255Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:30:44.257Z level=INFO fiber=#18 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:30:46.250Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:30:47.244Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:30:48.248Z level=INFO fiber=#22 message="https://main/5/1 - ok - 1000"
timestamp=2025-03-18T13:30:49.257Z level=INFO fiber=#23 message="mapper2-index = 7"
timestamp=2025-03-18T13:30:50.261Z level=INFO fiber=#22 message="https://main/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:30:50.263Z level=INFO fiber=#22 message="https://main/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:30:50.266Z level=INFO fiber=#23 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T13:30:52.273Z level=INFO fiber=#23 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:30:52.274Z level=INFO fiber=#23 message="https://main/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:30:52.278Z level=INFO fiber=#24 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:30:52.278Z level=INFO fiber=#25 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:30:52.279Z level=INFO fiber=#26 message="https://main/5/4 - aborted - from event"
timestamp=2025-03-18T13:30:52.297Z level=INFO fiber=#27 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:39:23.494Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:39:23.526Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/7/1,https://main/7/2"
timestamp=2025-03-18T13:39:23.531Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:39:24.543Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:39:25.537Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:39:25.553Z level=INFO fiber=#18 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:39:27.543Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:39:28.535Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:39:29.544Z level=INFO fiber=#22 message="https://main/5/1 - ok - 1000"
timestamp=2025-03-18T13:39:30.534Z level=INFO fiber=#23 message="mapper2-index = 7"
timestamp=2025-03-18T13:39:31.546Z level=INFO fiber=#23 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T13:39:31.550Z level=INFO fiber=#22 message="https://main/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:39:31.553Z level=INFO fiber=#22 message="https://main/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:39:33.550Z level=INFO fiber=#23 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:39:35.561Z level=INFO fiber=#22 message="https://main/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:39:35.564Z level=INFO fiber=#24 message="[
  \"https://main/1 - ok - 2000\",
  \"https://main/2 - ng - 2000 - Sleep NG after wait\",
  \"https://main/3 - ng - Sleep NG before wait\",
  \"https://main/4 - ng - 4000 - Sleep NG after wait\",
  \"https://main/5 - ok - 12000\",
  \"https://main/7 - ok - 10000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:47:49.566Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:47:49.596Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/5/5,https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T13:47:49.602Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:47:50.609Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:47:51.120Z level=INFO fiber=#21 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:47:51.609Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:47:53.612Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:47:54.606Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:47:55.119Z level=INFO fiber=#25 message="https://test/5/1 - ok - 1000"
timestamp=2025-03-18T13:47:56.125Z level=INFO fiber=#25 message="https://test/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:47:56.127Z level=INFO fiber=#25 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:47:56.615Z level=INFO fiber=#26 message="mapper2-index = 7"
timestamp=2025-03-18T13:47:57.126Z level=INFO fiber=#26 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T13:47:58.128Z level=INFO fiber=#26 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:47:58.129Z level=INFO fiber=#26 message="https://test/7/3 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:47:58.130Z level=INFO fiber=#27 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:47:58.130Z level=INFO fiber=#28 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:47:58.131Z level=INFO fiber=#29 message="https://test/5/4 - aborted - from event - test - abort_event"
timestamp=2025-03-18T13:47:58.134Z level=INFO fiber=#30 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:51:38.345Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:51:38.382Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/7/1,https://test/7/2"
timestamp=2025-03-18T13:51:38.387Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:51:39.397Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:51:39.913Z level=INFO fiber=#21 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:51:40.402Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:51:42.393Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:51:43.386Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:51:43.891Z level=INFO fiber=#25 message="https://test/5/1 - ok - 1000"
timestamp=2025-03-18T13:51:44.907Z level=INFO fiber=#25 message="https://test/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:51:44.907Z level=INFO fiber=#25 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:51:45.395Z level=INFO fiber=#26 message="mapper2-index = 7"
timestamp=2025-03-18T13:51:45.903Z level=INFO fiber=#26 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T13:51:46.917Z level=INFO fiber=#26 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:51:46.918Z level=INFO fiber=#25 message="https://test/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:51:46.920Z level=INFO fiber=#27 message="[
  \"https://test/1 - ok - 2000\",
  \"https://test/2 - ng - 2000 - Sleep NG after wait\",
  \"https://test/3 - ng - Sleep NG before wait\",
  \"https://test/4 - ng - 4000 - Sleep NG after wait\",
  \"https://test/5 - ok - 12000\",
  \"https://test/7 - ok - 10000\"
]"
```




### 全部同時実行からの最大２個まで同時実行

```plantuml
@startuml
robust "全体" as all

concise "https://test/1" as test1
concise "https://test/1/1" as test1_1

concise "https://test/2" as test2
concise "https://test/2/1" as test2_1
concise "https://test/2/2" as test2_2

concise "https://test/3" as test3
concise "https://test/3/1" as test3_1
concise "https://test/3/2" as test3_2
concise "https://test/3/3" as test3_3

concise "https://test/4" as test4
concise "https://test/4/1" as test4_1
concise "https://test/4/2" as test4_2
concise "https://test/4/3" as test4_3
concise "https://test/4/4" as test4_4

concise "https://test/5" as test5
concise "https://test/5/1" as test5_1
concise "https://test/5/2" as test5_2
concise "https://test/5/3" as test5_3
concise "https://test/5/4" as test5_4
compact concise "abort" as test54c
concise "https://test/5/5" as test5_5

concise "https://test/7" as test7
concise "https://test/7/1" as test7_1
compact concise "abort" as test71c
concise "https://test/7/2" as test7_2
compact concise "abort" as test72c
concise "https://test/7/3" as test7_3
concise "https://test/7/4" as test7_4
concise "https://test/7/5" as test7_5
concise "https://test/7/6" as test7_6
concise "https://test/7/7" as test7_7

@8
test5_4 -> test54c
test7_1 -> test71c
test7_2 -> test72c

@all
0 is 待機中
+1 is 処理中
+7 is 中断中

@test1
1 is 処理中
+1 is {hidden}
@test1_1
2 is 処理中
+1 is {hidden}

@test2
1 is 処理中 #pink
+2 is {hidden}

@test3
1 is 処理中 #pink
+0.01 is {hidden}

@test4
1 is 処理中 #pink
+4 is {hidden}

@test5
1 is 処理中
+5 is {hidden}
@test5_1
6 is 処理中
+1 is {hidden}
@test5_2
6 is 処理中 #pink
+2 is {hidden}
@test5_3
7 is 処理中 #pink
+0.01 is {hidden}
@test5_4
7 is 処理中 #pink
+4 is {hidden}
@test54c
8 is aborted #gray
+0.01 is {hidden}
@test5_5
8 is abort #gray
+0.01 is {hidden}

@test7
1 is 処理中
+7 is {hidden}
@test7_1
8 is 処理中
+1 is {hidden}
@test71c
8 is aborted #gray
+0.01 is {hidden}
@test7_2
8 is 処理中 #pink
+2 is {hidden}
@test72c
8 is aborted #gray
+0.01 is {hidden}

@enduml
```

#### MainRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:34:17.666Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:34:17.693Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/5/5,https://main/7/1,https://main/7/2,https://main/7/3,https://main/7/4,https://main/7/5,https://main/7/6,https://main/7/7"
timestamp=2025-03-18T13:34:17.700Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:34:18.716Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:34:19.714Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:34:19.730Z level=INFO fiber=#25 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:34:21.711Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:34:22.713Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:34:23.730Z level=INFO fiber=#27 message="https://main/5/1 - ok - 1000"
timestamp=2025-03-18T13:34:23.737Z level=INFO fiber=#27 message="https://main/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:34:24.714Z level=INFO fiber=#23 message="mapper2-index = 7"
timestamp=2025-03-18T13:34:24.719Z level=INFO fiber=#28 message="https://main/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:34:24.720Z level=INFO fiber=#28 message="https://main/5/5 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:34:24.723Z level=INFO fiber=#32 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:34:24.724Z level=INFO fiber=#33 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:34:24.725Z level=INFO fiber=#34 message="https://main/5/4 - aborted - from event"
timestamp=2025-03-18T13:34:24.726Z level=INFO fiber=#35 message="https://main/7/1 - aborted - from event"
timestamp=2025-03-18T13:34:24.726Z level=INFO fiber=#36 message="https://main/7/2 - aborted - from event"
timestamp=2025-03-18T13:34:24.735Z level=INFO fiber=#37 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:41:52.484Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:41:52.516Z level=INFO fiber=#15 message="[sites] : https://main/1/1,https://main/2/1,https://main/2/2,https://main/3/1,https://main/3/2,https://main/3/3,https://main/4/1,https://main/4/2,https://main/4/3,https://main/4/4,https://main/5/1,https://main/5/2,https://main/5/3,https://main/5/4,https://main/7/1,https://main/7/2"
timestamp=2025-03-18T13:41:52.526Z level=INFO fiber=#20 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:41:53.535Z level=INFO fiber=#18 message="mapper2-index = 1"
timestamp=2025-03-18T13:41:54.529Z level=INFO fiber=#19 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:41:54.545Z level=INFO fiber=#25 message="https://main/1/1 - ok - 1000"
timestamp=2025-03-18T13:41:56.525Z level=INFO fiber=#21 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:41:57.539Z level=INFO fiber=#22 message="mapper2-index = 5"
timestamp=2025-03-18T13:41:58.545Z level=INFO fiber=#27 message="https://main/5/1 - ok - 1000"
timestamp=2025-03-18T13:41:58.547Z level=INFO fiber=#27 message="https://main/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:41:59.530Z level=INFO fiber=#23 message="mapper2-index = 7"
timestamp=2025-03-18T13:41:59.549Z level=INFO fiber=#28 message="https://main/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:42:00.536Z level=INFO fiber=#30 message="https://main/7/1 - ok - 1000"
timestamp=2025-03-18T13:42:01.537Z level=INFO fiber=#31 message="https://main/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:42:02.553Z level=INFO fiber=#27 message="https://main/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:42:02.554Z level=INFO fiber=#32 message="[
  \"https://main/1 - ok - 2000\",
  \"https://main/2 - ng - 2000 - Sleep NG after wait\",
  \"https://main/3 - ng - Sleep NG before wait\",
  \"https://main/4 - ng - 4000 - Sleep NG after wait\",
  \"https://main/5 - ok - 10000\",
  \"https://main/7 - ok - 9000\"
]"
```

#### TestRuntime の場合

実行結果
```ts
timestamp=2025-03-18T13:48:51.957Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:48:51.986Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/5/5,https://test/7/1,https://test/7/2,https://test/7/3,https://test/7/4,https://test/7/5,https://test/7/6,https://test/7/7"
timestamp=2025-03-18T13:48:51.991Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:48:52.997Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:48:53.521Z level=INFO fiber=#28 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:48:54.003Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:48:55.995Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:48:56.996Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:48:57.514Z level=INFO fiber=#30 message="https://test/5/1 - ok - 1000"
timestamp=2025-03-18T13:48:57.516Z level=INFO fiber=#30 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:48:58.000Z level=INFO fiber=#31 message="https://test/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:48:58.001Z level=INFO fiber=#31 message="https://test/5/5 - abort - topIndex + lastIndex >= 10"
timestamp=2025-03-18T13:48:58.003Z level=INFO fiber=#32 message="mapper2-index = 5 - aborted - from event"
timestamp=2025-03-18T13:48:58.003Z level=INFO fiber=#33 message="mapper2-index = 7 - aborted - from event"
timestamp=2025-03-18T13:48:58.004Z level=INFO fiber=#34 message="https://test/5/4 - aborted - from event - test - abort_event"
timestamp=2025-03-18T13:48:58.009Z level=INFO fiber=#35 message="中断しました: All fibers interrupted without errors."
```

実行結果（※中断データを除外した場合）
```ts
timestamp=2025-03-18T13:52:51.605Z level=INFO fiber=#3 message=[start]
timestamp=2025-03-18T13:52:51.632Z level=INFO fiber=#18 message="[sites] : https://test/1/1,https://test/2/1,https://test/2/2,https://test/3/1,https://test/3/2,https://test/3/3,https://test/4/1,https://test/4/2,https://test/4/3,https://test/4/4,https://test/5/1,https://test/5/2,https://test/5/3,https://test/5/4,https://test/7/1,https://test/7/2"
timestamp=2025-03-18T13:52:51.638Z level=INFO fiber=#23 message="mapper2-index = 3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:52:52.642Z level=INFO fiber=#21 message="mapper2-index = 1"
timestamp=2025-03-18T13:52:53.152Z level=INFO fiber=#28 message="https://test/1/1 - ok - 1000"
timestamp=2025-03-18T13:52:53.641Z level=INFO fiber=#22 message="mapper2-index = 2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:52:55.638Z level=INFO fiber=#24 message="mapper2-index = 4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:52:56.639Z level=INFO fiber=#25 message="mapper2-index = 5"
timestamp=2025-03-18T13:52:57.158Z level=INFO fiber=#30 message="https://test/5/1 - ok - 1000"
timestamp=2025-03-18T13:52:57.160Z level=INFO fiber=#30 message="https://test/5/3 - ng - Sleep NG before wait"
timestamp=2025-03-18T13:52:57.655Z level=INFO fiber=#31 message="https://test/5/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:52:58.640Z level=INFO fiber=#26 message="mapper2-index = 7"
timestamp=2025-03-18T13:52:59.155Z level=INFO fiber=#33 message="https://test/7/1 - ok - 1000"
timestamp=2025-03-18T13:52:59.175Z level=INFO fiber=#30 message="https://test/5/4 - ng - 4000 - Sleep NG after wait"
timestamp=2025-03-18T13:52:59.655Z level=INFO fiber=#34 message="https://test/7/2 - ng - 2000 - Sleep NG after wait"
timestamp=2025-03-18T13:52:59.656Z level=INFO fiber=#35 message="[
  \"https://test/1 - ok - 2000\",
  \"https://test/2 - ng - 2000 - Sleep NG after wait\",
  \"https://test/3 - ng - Sleep NG before wait\",
  \"https://test/4 - ng - 4000 - Sleep NG after wait\",
  \"https://test/5 - ok - 10000\",
  \"https://test/7 - ok - 9000\"
]"
```


## ソースコード

```ts
import { describe, test } from 'vitest'
import {
  Effect,
  pipe,
  Either,
  Exit,
  Cause,
  Context,
  Data,
  Schema,
  Layer,
  Duration,
  ManagedRuntime,
  Config,
  ConfigProvider,
  Logger,
  LogLevel,
  Array
} from 'effect'
import { UnknownException } from 'effect/Cause'

class SleepNGBeforeError extends Data.TaggedError('SleepNGBeforeError')<{}> {
  getMessage(site: string) {
    return `${site} - ng - Sleep NG before wait`
  }

  static isClass(test: any): test is SleepNGBeforeError {
    return test._tag === SleepNGBeforeError.name
  }
}

class SleepNGAfterError extends Data.TaggedError('SleepNGAfterError')<{ wait: number }> {
  getMessage(site: string) {
    return `${site} - ng - ${this.wait} - Sleep NG after wait`
  }

  static isClass(test: any): test is SleepNGAfterError {
    return test._tag === SleepNGAfterError.name
  }
}

class AlreadyAbortError extends Data.TaggedError('AlreadyAbortError')<{}> {
  static getMessage(site: string) {
    return `${site} - aborted - from event`
  }
}

class OriginAbortError extends Data.TaggedError('OriginAbortError')<{
  site: string
  reason: string
}> {
  getMessage() {
    return `${this.site} - abort - ${this.reason}`
  }

  static siteCheck(abortAction: Function, topIndex?: number) {
    return (site: string) => {
      return Effect.gen(function* () {
        const lastIndex = OkData.getLastIndex(site)
        let originAbortError = undefined
        if (Number.isNaN(lastIndex)) {
          const reason = `${lastIndex} is NaN`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (lastIndex === undefined) {
          const reason = `${lastIndex} is undefined`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (site[site.length - 2] !== '/') {
          const reason = `lastIndex >= 10`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (topIndex && topIndex + lastIndex >= 10) {
          const reason = `topIndex + lastIndex >= 10`
          originAbortError = new OriginAbortError({ site, reason })
        }

        if (originAbortError !== undefined) {
          yield* Effect.log(originAbortError.getMessage())
          abortAction()
          return Effect.fail(originAbortError)
        }

        return Effect.succeed(site)
      })
    }
  }
}

class OkData extends Schema.Class<OkData>('OkData')({
  wait: Schema.Number
}) {
  static isClass(test: any): test is OkData {
    return test instanceof OkData
  }

  static getLastIndex(site: string) {
    const index = site.slice(-1)
    return Number(index)
  }

  getMessage(site: string) {
    return `${site} - ok - ${this.wait}`
  }
}

type AllNgData = SleepNGBeforeError | SleepNGAfterError | UnknownException

class TopSleepNGError extends Data.TaggedError('TopSleepNGError')<{ ngData: AllNgData }> {
  static isClass(test: any): test is TopSleepNGError {
    return test._tag === TopSleepNGError.name
  }

  getLastMessage() {
    const lastMessage =
      this.ngData instanceof UnknownException
        ? ' - ng - UnknownException'
        : this.ngData.getMessage('')
    return lastMessage
  }

  getMessage(site: string) {
    const index = TopOkData.getTopIndex(site)
    const lastMessage = this.getLastMessage()
    return `mapper2-index = ${index}${lastMessage}`
  }

  getTopMessage(site: string) {
    const lastMessage = this.getLastMessage()
    return `${site.substring(0, site.length - 2)}${lastMessage}`
  }
}

class TopOkData extends Schema.Class<TopOkData>('TopOkData')({
  site: Schema.String,
  wait: Schema.Number
}) {
  static isClass(test: any): test is TopOkData {
    return test instanceof TopOkData
  }

  static getTopIndex(site: string) {
    const index = site.substring(site.length - 3, site.length - 2)
    return Number(index)
  }

  static getMessage(site: string) {
    const index = TopOkData.getTopIndex(site)
    return `mapper2-index = ${index}`
  }

  static getAbortMessage(site: string) {
    const index = TopOkData.getTopIndex(site)
    return `mapper2-index = ${index} - aborted - from event`
  }

  getTopMessage(opWait: number) {
    return `${this.site.substring(0, this.site.length - 2)} - ok - ${this.wait + opWait}`
  }
}

const sleep = (wait: number) =>
  Effect.tryPromise<OkData>(
    () =>
      new Promise((resolve, reject) => {
        const waitSeconds = wait / 1000
        if (waitSeconds % 3 === 0) {
          reject(new SleepNGBeforeError())
        } else if (waitSeconds % 2 === 0) {
          setTimeout(() => reject(new SleepNGAfterError({ wait })), wait)
        } else {
          setTimeout(() => resolve(new OkData({ wait })), wait)
        }
      })
  )

const testOptions = {
  timeout: 1000 * 100
}

const sumNumber = (chunkSize: number) => (a: number[], b: number[]) => {
  function addArray(num: number) {
    if (a.length === chunkSize) {
      const aMin = Math.min(...a)
      const aMinIndex = a.indexOf(aMin)
      a[aMinIndex] += num
    } else {
      a.push(num)
    }
  }

  b.forEach((bNum) => addArray(bNum))

  return a
}

function getWaitNumber(index: number) {
  const wait = index * 1000
  return wait
}

function mapError_sleepNg<T>(effectAndThen: Effect.Effect<T, UnknownException, never>) {
  const effectAll = Effect.mapError(effectAndThen, (err) => {
    if (SleepNGBeforeError.isClass(err.error)) {
      return err.error
    } else if (SleepNGAfterError.isClass(err.error)) {
      return err.error
    } else {
      Effect.runPromise(Effect.log(`mapError_sleepNg : UnknownException : ${err}`))
      return err
    }
  })
  return effectAll
}

function mapNumber_fromData<T, U>(data: Either.Either<T, U>) {
  const result = Either.mapBoth(data, {
    onLeft: (left) => {
      if (OkData.isClass(left)) {
        return left.wait
      } else if (SleepNGBeforeError.isClass(left)) {
        return 0
      } else if (SleepNGAfterError.isClass(left)) {
        return left.wait
      }

      return 0
    },
    onRight: (right) => {
      if (OkData.isClass(right)) {
        return right.wait
      }

      return 0
    }
  })

  return Either.isLeft(result) ? result.left : result.right
}

const do_sleep1 = (wait: number) =>
  Effect.try(() => {
    const sleepEffect = sleep(wait)
    const effectAll = mapError_sleepNg(sleepEffect)
    return effectAll
  })

const do_sleep2 = (site: string) => (wait: number) =>
  Effect.try(() => {
    const sleepEffect = sleep(wait)
    const effectAndThen = Effect.andThen(sleepEffect, (okData) => {
      const topOkData = new TopOkData({ site, wait: okData.wait })
      return topOkData
    })
    const effectAll = mapError_sleepNg(effectAndThen)
    return effectAll
  })

class Abort_Service extends Context.Tag('Abort_Service')<
  Abort_Service,
  {
    readonly return_abort_error: (
      site: string
    ) => Effect.Effect<Either.Either<never, AlreadyAbortError>, never, never>
    readonly abort_event: (runtime: any, site: string) => void
  }
>() {
  static readonly Live = Layer.succeed(Abort_Service, {
    return_abort_error: function (site: string) {
      return Effect.gen(function* () {
        const alreadyAbortError = new AlreadyAbortError()
        yield* Effect.log(AlreadyAbortError.getMessage(site))
        return Either.left(alreadyAbortError)
      })
    },
    abort_event: function (runtime: any, site: string) {
      runtime.runSync(Effect.log(AlreadyAbortError.getMessage(site)))
    }
  })

  static readonly LiveTest = Layer.succeed(Abort_Service, {
    return_abort_error: function (site: string) {
      return Effect.gen(function* () {
        const alreadyAbortError = new AlreadyAbortError()
        yield* Effect.log(`${site} - aborted - from event - test - return_abort_error`)
        return Either.left(alreadyAbortError)
      })
    },
    abort_event: function (runtime: any, site: string) {
      runtime.runSync(Effect.log(`${site} - aborted - from event - test - abort_event`))
    }
  })
}

class AAA_Abort_Service_Test extends Effect.Service<Abort_Service>()('Abort_Service', {
  succeed: {
    return_abort_error: function (site: string) {
      return Effect.gen(function* () {
        const alreadyAbortError = new AlreadyAbortError()
        yield* Effect.log(`${site} - aborted - from event - test - return_abort_error`)
        return Either.left(alreadyAbortError)
      })
    },
    abort_event: function (runtime: any, site: string) {
      runtime.runSync(Effect.log(`${site} - aborted - from event - test - abort_event`))
    }
  }
}) {}

class Main_Service extends Context.Tag('Main_Service')<
  Main_Service,
  {
    readonly abort_check: (
      abortAction: Function,
      topIndex?: number
    ) => (
      site: string
    ) => Effect.Effect<
      Effect.Effect<never, OriginAbortError, never> | Effect.Effect<string, never, never>,
      never,
      never
    >
    readonly do_effect: (
      abort_result: string
    ) => Effect.Effect<
      Effect.Effect<OkData, UnknownException | SleepNGBeforeError | SleepNGAfterError, never>,
      UnknownException,
      never
    >
  }
>() {
  static readonly Live = Layer.succeed(Main_Service, {
    abort_check: (abortAction, topIndex?) => (site: string) =>
      pipe(site, OriginAbortError.siteCheck(abortAction, topIndex)),
    do_effect: (abortResult) => pipe(abortResult, OkData.getLastIndex, getWaitNumber, do_sleep1)
  })

  static readonly LiveTest = Layer.succeed(Main_Service, {
    abort_check: (abortAction, topIndex?) => (site: string) => {
      return Effect.gen(function* () {
        const index = site.slice(-1)
        const lastIndex = Number(index)
        let originAbortError = undefined
        let reason = undefined
        if (Number.isNaN(lastIndex)) {
          reason = `${lastIndex} is NaN`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (lastIndex === undefined) {
          reason = `${lastIndex} is undefined`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (site[site.length - 2] !== '/') {
          reason = `lastIndex >= 10`
          originAbortError = new OriginAbortError({ site, reason })
        } else if (topIndex && topIndex + lastIndex >= 10) {
          reason = `topIndex + lastIndex >= 10`
          originAbortError = new OriginAbortError({ site, reason })
        }

        if (originAbortError !== undefined) {
          yield* Effect.log(`${site} - abort - ${reason}`)
          abortAction()
          return Effect.fail(originAbortError)
        }

        return Effect.succeed(site)
      })
    },
    do_effect: (abortResult) => {
      const index = abortResult.slice(-1)
      const lastIndex = Number(index)
      const wait = lastIndex * 1000
      const testWait = wait / 2

      if (lastIndex % 3 === 0) {
        return Effect.succeed(Effect.fail(new SleepNGBeforeError()))
      } else if (lastIndex % 2 === 0) {
        return Effect.andThen(
          Effect.sleep(Duration.millis(testWait)),
          Effect.succeed(Effect.fail(new SleepNGAfterError({ wait })))
        )
      } else {
        return Effect.andThen(
          Effect.sleep(Duration.millis(testWait)),
          Effect.succeed(Effect.succeed(new OkData({ wait: lastIndex * 1000 })))
        )
      }
    }
  })
}

class Result_Service extends Context.Tag('Result_Service')<
  Result_Service,
  {
    readonly ok_action: (okData: OkData, site: string) => Effect.Effect<void, never, never>
    readonly ng_action: (
      ngData: UnknownException | SleepNGBeforeError | SleepNGAfterError,
      site: string
    ) => Effect.Effect<void, never, never>
  }
>() {
  static readonly Live = Layer.succeed(Result_Service, {
    ok_action: (okData, site) => {
      return Effect.gen(function* () {
        const message = okData.getMessage(site)
        yield* Effect.log(message)
      })
    },
    ng_action: (ngData, site) => {
      return Effect.gen(function* () {
        if (SleepNGBeforeError.isClass(ngData)) {
          const message = ngData.getMessage(site)
          yield* Effect.log(message)
        } else if (SleepNGAfterError.isClass(ngData)) {
          const message = ngData.getMessage(site)
          yield* Effect.log(message)
        }
      })
    }
  })
}

class Top_Main_Service extends Context.Tag('Top_Main_Service')<
  Top_Main_Service,
  {
    readonly abort_check: (
      abortAction: Function
    ) => (
      site: string
    ) => Effect.Effect<
      Effect.Effect<never, OriginAbortError, never> | Effect.Effect<string, never, never>,
      never,
      never
    >
    readonly do_effect: (
      site: string
    ) => Effect.Effect<
      Effect.Effect<TopOkData, UnknownException | SleepNGBeforeError | SleepNGAfterError, never>,
      UnknownException,
      never
    >
    readonly top_abort_event: (runtime: any, site: string) => void
  }
>() {
  static readonly Live = Layer.succeed(Top_Main_Service, {
    abort_check: (abortAction) => (site: string) => {
      const result = pipe(site, OriginAbortError.siteCheck(abortAction))
      return result
    },
    do_effect: (site) => pipe(site, TopOkData.getTopIndex, getWaitNumber, do_sleep2(site)),
    top_abort_event: function (runtime: any, site: string) {
      runtime.runSync(Effect.log(TopOkData.getAbortMessage(site)))
    }
  })
}

const MainLayer = Layer.mergeAll(
  Abort_Service.Live,
  Main_Service.Live,
  Result_Service.Live,
  Top_Main_Service.Live
)

const TestLayer = Layer.mergeAll(
  Layer.setConfigProvider(
    ConfigProvider.fromMap(
      new Map([
        // [
        //   'VITE_MY_ARRAY',
        //   'https://test/1, https://test/2, https://test/3, https://test/4, https://test/5, https://test/10'
        // ],
        [
          'VITE_MY_ARRAY',
          'https://test/1, https://test/2, https://test/3, https://test/4, https://test/5'
        ],
        ['VITE_MY_ARRAY_ARRAY_1', 'https://test/1/1'],
        // ['VITE_MY_ARRAY_ARRAY_1', ''],
        ['VITE_MY_ARRAY_ARRAY_2', 'https://test/2/1, https://test/2/2'],
        // ['VITE_MY_ARRAY_ARRAY_2', ''],
        ['VITE_MY_ARRAY_ARRAY_3', 'https://test/3/1, https://test/3/2, https://test/3/3'],
        // ['VITE_MY_ARRAY_ARRAY_3', ''],
        [
          'VITE_MY_ARRAY_ARRAY_4',
          'https://test/4/1, https://test/4/2, https://test/4/3, https://test/4/4'
        ],
        // ['VITE_MY_ARRAY_ARRAY_4', ''],
        // [
        //   'VITE_MY_ARRAY_ARRAY_5',
        //   'https://test/5/1, https://test/5/2, https://test/5/3, https://test/5/4, https://test/5/5'
        // ],
        [
          'VITE_MY_ARRAY_ARRAY_5',
          'https://test/5/1, https://test/5/2, https://test/5/3, https://test/5/4'
        ],
        // ['VITE_MY_ARRAY_ARRAY_5', ''],
        // [
        //   'VITE_MY_ARRAY_ARRAY_7',
        //   'https://test/7/1, https://test/7/2, https://test/7/3, https://test/7/4, https://test/7/5, https://test/7/6, https://test/7/7'
        // ]
        ['VITE_MY_ARRAY_ARRAY_7', 'https://test/7/1, https://test/7/2']
      ])
    )
  ),
  AAA_Abort_Service_Test.Default,
  Main_Service.LiveTest,
  Result_Service.Live,
  Top_Main_Service.Live
)

const NoneLogLayer = Layer.mergeAll(
  Layer.setConfigProvider(
    ConfigProvider.fromMap(
      new Map([
        // [
        //   'VITE_MY_ARRAY',
        //   'https://test/1, https://main/2, https://test/3, https://main/4, https://test/5, https://main/10'
        // ],
        [
          'VITE_MY_ARRAY',
          'https://test/1, https://main/2, https://test/3, https://main/4, https://test/5'
        ],
        ['VITE_MY_ARRAY_ARRAY_1', ''],
        ['VITE_MY_ARRAY_ARRAY_2', ''],
        ['VITE_MY_ARRAY_ARRAY_3', ''],
        ['VITE_MY_ARRAY_ARRAY_4', ''],
        ['VITE_MY_ARRAY_ARRAY_5', ''],
        [
          'VITE_MY_ARRAY_ARRAY_7',
          'https://test/7/1, https://main/7/2, https://test/7/3, https://main/7/4, https://test/7/5, https://main/7/6, https://test/7/7'
        ]
      ])
    )
  ),
  Abort_Service.Live,
  Main_Service.Live,
  Result_Service.Live,
  Top_Main_Service.Live,
  Logger.minimumLogLevel(LogLevel.None)
)

const MainRuntime = ManagedRuntime.make(MainLayer)
const TestRuntime = ManagedRuntime.make(TestLayer)
const NoneLogRuntime = ManagedRuntime.make(NoneLogLayer)

function mapper1(runtime: any, abortController: AbortController, topIndex?: number) {
  return (site: string) =>
    Effect.gen(function* () {
      const abortService = yield* Abort_Service
      const mainService = yield* Main_Service
      const resultService = yield* Result_Service

      const abortEvent = () => abortService.abort_event(runtime, site)
      if (abortController.signal.aborted) {
        return abortService.return_abort_error(site)
      }
      abortController.signal.addEventListener('abort', abortEvent)
      function removeEvent() {
        abortController.signal.removeEventListener('abort', abortEvent)
      }
      const abortAction = () => {
        removeEvent()
        abortController.abort()
      }

      const abortCheck = yield* yield* mainService.abort_check(abortAction, topIndex)(site)
      const effect = yield* mainService.do_effect(abortCheck)
      const either = yield* Effect.either(effect)

      if (Either.isRight(either)) {
        const okData = either.right
        yield* resultService.ok_action(okData, site)
      } else if (Either.isLeft(either)) {
        const ngData = either.left
        yield* resultService.ng_action(ngData, site)
      }

      removeEvent()
      return either
    })
}

function mapper2(runtime: any, abortController: AbortController, options: { concurrency: number }) {
  return (sites: string[]) =>
    Effect.gen(function* () {
      const site = sites[0]
      const abortService = yield* Abort_Service
      const topMainService = yield* Top_Main_Service

      if (abortController.signal.aborted) {
        return abortService.return_abort_error(site)
      }
      const abortEvent = () => topMainService.top_abort_event(runtime, site)
      abortController.signal.addEventListener('abort', abortEvent)
      function removeEvent() {
        abortController.signal.removeEventListener('abort', abortEvent)
      }
      const abortAction = () => {
        removeEvent()
        abortController.abort()
      }

      const abortCheck = yield* yield* topMainService.abort_check(abortAction)(site)
      const effect2 = yield* topMainService.do_effect(abortCheck)
      const either2 = yield* Effect.either(effect2)

      if (Either.isLeft(either2)) {
        const ngData = either2.left
        const topNgData = new TopSleepNGError({ ngData })

        const message = topNgData.getMessage(site)
        yield* Effect.log(message)

        const topMessage = topNgData.getTopMessage(site)
        removeEvent()
        return topMessage
      } else if (Either.right(either2)) {
        const topOkData = either2.right

        const message = TopOkData.getMessage(site)
        yield* Effect.log(message)

        const either1 = yield* Effect.all(
          sites.map(mapper1(runtime, abortController, TopOkData.getTopIndex(site))),
          options
        )
        const arrayEither1: number[] = either1.map(mapNumber_fromData as any)
        const concurrency = options['concurrency']
        const chunkArray = Array.chunksOf(arrayEither1, concurrency)
        const waitNumber = Array.reduce(chunkArray, [0], sumNumber(concurrency))

        const topMessage = topOkData.getTopMessage(Math.max(...waitNumber))
        removeEvent()
        return topMessage
      }

      removeEvent()
      return either2
    })
}

const sitesData = Effect.gen(function* () {
  const config = yield* Config.array(Config.string(), 'VITE_MY_ARRAY')
  return config
})

const sitesData2 = Effect.gen(function* () {
  const config: string[][] = []
  const array1 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_1')
  const array2 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_2')
  const array3 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_3')
  const array4 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_4')
  const array5 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_5')
  const array7 = yield* Config.array(Config.string(), 'VITE_MY_ARRAY_ARRAY_7')
  const addArray = (array: string[]) => {
    if (array && array.length > 0 && array[0] != '') config.push(array)
  }
  addArray(array1)
  addArray(array2)
  addArray(array3)
  addArray(array4)
  addArray(array5)
  addArray(array7)
  return config
})

describe('effect-ts 非同期処理１つの配列', () => {
  test(
    '使い方１ーMainRuntimeー全部同時実行: Requirements管理:本番or非同期テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://main/1',
      //   'https://main/2',
      //   'https://main/3',
      //   'https://main/4',
      //   'https://main/5',
      //   'https://main/10'
      // ]
      const sites = await MainRuntime.runPromise(sitesData)

      MainRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(MainRuntime, abortController)), {
        concurrency: sites.length
      })
      const exit = await MainRuntime.runPromiseExit(effect, { signal: abortController.signal })

      MainRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方１ーTestRuntimeー全部同時実行: Requirements管理:高速テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://test/1',
      //   'https://test/2',
      //   'https://test/3',
      //   'https://test/4',
      //   'https://test/5',
      //   'https://test/10'
      // ]
      const sites = await TestRuntime.runPromise(sitesData)

      TestRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(TestRuntime, abortController)), {
        concurrency: sites.length
      })
      const exit = await TestRuntime.runPromiseExit(effect, { signal: abortController.signal })

      TestRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方１ーNoneLogRuntimeー全部同時実行: Requirements管理:ログなしテスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://test/1',
      //   'https://main/2',
      //   'https://test/3',
      //   'https://main/4',
      //   'https://test/5',
      //   'https://main/10'
      // ]
      const sites = await NoneLogRuntime.runPromise(sitesData)

      NoneLogRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(NoneLogRuntime, abortController)), {
        concurrency: sites.length
      })
      const exit = await NoneLogRuntime.runPromiseExit(effect, { signal: abortController.signal })

      NoneLogRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方２ーMainRuntimeー最大２個まで同時実行: Requirements管理:本番or非同期テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://main/1',
      //   'https://main/2',
      //   'https://main/3',
      //   'https://main/4',
      //   'https://main/5',
      //   'https://main/10'
      // ]
      const sites = await MainRuntime.runPromise(sitesData)

      MainRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(MainRuntime, abortController)), {
        concurrency: 2
      })
      const exit = await MainRuntime.runPromiseExit(effect, { signal: abortController.signal })

      MainRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方２ーTestRuntimeー最大２個まで同時実行: Requirements管理:高速テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://test/1',
      //   'https://test/2',
      //   'https://test/3',
      //   'https://test/4',
      //   'https://test/5',
      //   'https://test/10'
      // ]
      const sites = await TestRuntime.runPromise(sitesData)

      TestRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(TestRuntime, abortController)), {
        concurrency: 2
      })
      const exit = await TestRuntime.runPromiseExit(effect, { signal: abortController.signal })

      TestRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方２ーNoneLogRuntimeー最大２個まで同時実行: Requirements管理:ログなしテスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   'https://test/1',
      //   'https://main/2',
      //   'https://test/3',
      //   'https://main/4',
      //   'https://test/5',
      //   'https://main/10'
      // ]
      const sites = await NoneLogRuntime.runPromise(sitesData)

      NoneLogRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(sites.map(mapper1(NoneLogRuntime, abortController)), {
        concurrency: 2
      })
      const exit = await NoneLogRuntime.runPromiseExit(effect, { signal: abortController.signal })

      NoneLogRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
})

describe('effect-ts 非同期処理２つの配列', () => {
  test(
    '使い方１ーMainRuntimeー全部同時実行からの全部同時実行: Requirements管理:本番or非同期テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await MainRuntime.runPromise(sitesData2)

      MainRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(MainRuntime, abortController, { concurrency: Number.MAX_VALUE })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await MainRuntime.runPromiseExit(effect, { signal: abortController.signal })

      MainRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方１ーTestRuntimeー全部同時実行からの全部同時実行: Requirements管理:高速テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await TestRuntime.runPromise(sitesData2)

      TestRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(TestRuntime, abortController, { concurrency: Number.MAX_VALUE })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await TestRuntime.runPromiseExit(effect, { signal: abortController.signal })

      TestRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方２ーMainRuntimeー全部同時実行からの直列実行: Requirements管理:本番or非同期テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await MainRuntime.runPromise(sitesData2)

      MainRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(MainRuntime, abortController, { concurrency: 1 })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await MainRuntime.runPromiseExit(effect, { signal: abortController.signal })

      MainRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方２ーTestRuntimeー全部同時実行からの直列実行: Requirements管理:高速テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await TestRuntime.runPromise(sitesData2)

      TestRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(TestRuntime, abortController, { concurrency: 1 })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await TestRuntime.runPromiseExit(effect, { signal: abortController.signal })

      TestRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方３ーMainRuntimeー全部同時実行からの最大２個まで同時実行: Requirements管理:本番or非同期テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await MainRuntime.runPromise(sitesData2)

      MainRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(MainRuntime, abortController, { concurrency: 2 })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await MainRuntime.runPromiseExit(effect, { signal: abortController.signal })

      MainRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
  test(
    '使い方３ーTestRuntimeー全部同時実行からの最大２個まで同時実行: Requirements管理:高速テスト用',
    testOptions,
    async () => {
      const abortController = new AbortController()

      Effect.runPromise(Effect.log('[start]'))

      // const sites = [
      //   [
      //     'https://test/5/1',
      //     'https://test/5/2',
      //     'https://test/5/3',
      //     'https://test/5/4',
      //     'https://test/5/5'
      //   ]
      // ]
      const sites = await TestRuntime.runPromise(sitesData2)

      TestRuntime.runPromise(Effect.log(`[sites] : ${sites}`))

      const effect = await Effect.all(
        sites.map(mapper2(TestRuntime, abortController, { concurrency: 2 })),
        {
          concurrency: Number.MAX_VALUE
        }
      )
      const exit = await TestRuntime.runPromiseExit(effect, { signal: abortController.signal })

      TestRuntime.runPromise(
        Effect.log(
          Exit.match(exit, {
            onFailure: (cause) => `中断しました: ${Cause.pretty(cause)}`,
            onSuccess: (either) => either
          })
        )
      )
    }
  )
})
```