Skip to content

Commit 7114c1b

Browse files
authored
Merge pull request #9 from Innmind/error-handling
Improve error handling
2 parents f229a26 + d9d8e73 commit 7114c1b

21 files changed

Lines changed: 448 additions & 252 deletions

src/Activities.php

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
use Innmind\CLI\Console;
77
use Innmind\OperatingSystem\OperatingSystem;
88
use Innmind\Time\Period;
9-
use Innmind\Immutable\Set;
9+
use Innmind\Immutable\{
10+
Set,
11+
Attempt,
12+
Sequence,
13+
};
1014

1115
final class Activities
1216
{
@@ -33,10 +37,13 @@ private function __construct(
3337
$this->activities = $activities;
3438
}
3539

40+
/**
41+
* @return Attempt<Console>
42+
*/
3643
public function __invoke(
3744
Console $console,
3845
OperatingSystem $os,
39-
): Console {
46+
): Attempt {
4047
// If no activities yet we wait a little bit to avoid always calling
4148
// this method.
4249
// The better approach would be to use sockets and to monitor them so we
@@ -46,27 +53,32 @@ public function __invoke(
4653
// exit this method periodically to allow the source to be restarted in
4754
// order to check if any agent crashed in order to restart it.
4855
if (\count($this->activities) === 0) {
49-
$_ = $os
56+
return $os
5057
->process()
5158
->halt(Period::millisecond(500))
52-
->unwrap();
59+
->map(static fn() => $console);
5360
}
5461

55-
while ($activity = \array_shift($this->activities)) {
56-
$this->iteration->start();
57-
$console = ($this->trigger)(
58-
$console,
59-
$os,
60-
$activity,
61-
$this->triggers,
62-
);
62+
$activities = Sequence::of(...$this->activities);
63+
$this->activities = [];
6364

64-
if ($activity !== Activity::start) {
65-
$console = $this->iteration->end($console);
66-
}
67-
}
65+
return $activities
66+
->sink($console)
67+
->attempt(function($console, $activity) use ($os) {
68+
$this->iteration->start();
69+
$console = ($this->trigger)(
70+
$console,
71+
$os,
72+
$activity,
73+
$this->triggers,
74+
);
75+
76+
if ($activity !== Activity::start) {
77+
return $console->flatMap($this->iteration->end(...));
78+
}
6879

69-
return $console;
80+
return $console;
81+
});
7082
}
7183

7284
/**

src/Command/Work.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function __invoke(Console $console): Attempt
4646
static fn() => Triggers::cases(),
4747
);
4848

49-
return Attempt::result(($this->monitor)($console, Set::of(...$triggers)));
49+
return ($this->monitor)($console, Set::of(...$triggers));
5050
}
5151

5252
/**

src/Iteration.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
namespace Innmind\LabStation;
55

66
use Innmind\CLI\Console;
7-
use Innmind\Immutable\Str;
7+
use Innmind\Immutable\{
8+
Str,
9+
Attempt,
10+
};
811

912
final class Iteration
1013
{
@@ -20,17 +23,20 @@ public function failing(): void
2023
$this->shouldClearTerminal = false;
2124
}
2225

23-
public function end(Console $console): Console
26+
/**
27+
* @return Attempt<Console>
28+
*/
29+
public function end(Console $console): Attempt
2430
{
2531
if (!$this->shouldClearTerminal) {
26-
return $console;
32+
return Attempt::result($console);
2733
}
2834

2935
if ($console->options()->contains('keep-output')) {
30-
return $console;
36+
return Attempt::result($console);
3137
}
3238

3339
// clear terminal
34-
return $console->output(Str::of("\033[2J\033[H"))->unwrap();
40+
return $console->output(Str::of("\033[2J\033[H"));
3541
}
3642
}

src/Monitor.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Innmind\Immutable\{
1010
Set,
1111
Sequence,
12+
Attempt,
1213
};
1314

1415
final class Monitor
@@ -36,8 +37,10 @@ public function __construct(
3637

3738
/**
3839
* @param Set<Triggers> $triggers
40+
*
41+
* @return Attempt<Console>
3942
*/
40-
public function __invoke(Console $console, Set $triggers): Console
43+
public function __invoke(Console $console, Set $triggers): Attempt
4144
{
4245
$project = $console->workingDirectory();
4346
$scheduler = Scheduler::of($this->os);
@@ -46,19 +49,15 @@ public function __invoke(Console $console, Set $triggers): Console
4649
$this->iteration,
4750
$triggers,
4851
);
49-
/** @var array{Console, boolean} */
50-
$carry = [$console, false];
5152

52-
[$console] = $scheduler
53-
->sink($carry)
53+
return $scheduler
54+
->sink(Attempt::result($console))
5455
->with(
5556
new Monitor\Loop(
5657
$this->agents,
5758
$activities,
5859
$project,
5960
),
6061
);
61-
62-
return $console;
6362
}
6463
}

src/Monitor/Loop.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Innmind\OperatingSystem\OperatingSystem;
1313
use Innmind\Url\Path;
1414
use Innmind\Immutable\{
15+
Attempt,
1516
Sequence,
1617
Predicate\Instance,
1718
};
@@ -22,6 +23,7 @@ final class Loop
2223
private Sequence $agents;
2324
private Activities $activities;
2425
private Path $project;
26+
private bool $started = false;
2527

2628
/**
2729
* @param Sequence<Agent> $agents
@@ -37,22 +39,22 @@ public function __construct(
3739
}
3840

3941
/**
40-
* @param array{Console, boolean} $carry
41-
* @param Continuation<array{Console, boolean}> $continuation
42+
* @param Attempt<Console> $console
43+
* @param Continuation<Attempt<Console>> $continuation
4244
*
43-
* @return Continuation<array{Console, boolean}>
45+
* @return Continuation<Attempt<Console>>
4446
*/
4547
public function __invoke(
46-
array $carry,
48+
Attempt $console,
4749
OperatingSystem $os,
4850
Continuation $continuation,
4951
): Continuation {
50-
[$console, $started] = $carry;
52+
if (!$this->started) {
53+
$this->started = true;
5154

52-
if (!$started) {
5355
return $continuation
5456
->schedule($this->agents->map($this->buildTask(...)))
55-
->carryWith([$console, true]);
57+
->carryWith($console);
5658
}
5759

5860
$continuation = $continuation->schedule(
@@ -62,12 +64,14 @@ public function __invoke(
6264
->map($this->buildTask(...)),
6365
);
6466

65-
$console = ($this->activities)(
66-
$console,
67-
$os,
67+
return $console->match(
68+
fn($console) => $continuation->carryWith(
69+
($this->activities)($console, $os),
70+
),
71+
static fn($e) => $continuation
72+
->carryWith(Attempt::error($e))
73+
->terminate(),
6874
);
69-
70-
return $continuation->carryWith([$console, $started]);
7175
}
7276

7377
/**

src/Trigger.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,22 @@
55

66
use Innmind\CLI\Console;
77
use Innmind\OperatingSystem\OperatingSystem;
8-
use Innmind\Immutable\Set;
8+
use Innmind\Immutable\{
9+
Set,
10+
Attempt,
11+
};
912

1013
interface Trigger
1114
{
1215
/**
1316
* @param Set<Triggers> $triggers
17+
*
18+
* @return Attempt<Console>
1419
*/
1520
public function __invoke(
1621
Console $console,
1722
OperatingSystem $os,
1823
Activity $activity,
1924
Set $triggers,
20-
): Console;
25+
): Attempt;
2126
}

src/Trigger/All.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
};
1010
use Innmind\CLI\Console;
1111
use Innmind\OperatingSystem\OperatingSystem;
12-
use Innmind\Immutable\Set;
12+
use Innmind\Immutable\{
13+
Set,
14+
Sequence,
15+
Attempt,
16+
};
1317

1418
final class All implements Trigger
1519
{
@@ -30,11 +34,14 @@ public function __invoke(
3034
OperatingSystem $os,
3135
Activity $activity,
3236
Set $triggers,
33-
): Console {
34-
foreach ($this->triggers as $trigger) {
35-
$console = $trigger($console, $os, $activity, $triggers);
36-
}
37-
38-
return $console;
37+
): Attempt {
38+
return Sequence::of(...$this->triggers)
39+
->sink($console)
40+
->attempt(static fn($console, $trigger) => $trigger(
41+
$console,
42+
$os,
43+
$activity,
44+
$triggers,
45+
));
3946
}
4047
}

0 commit comments

Comments
 (0)