Skip to content

Commit 417860a

Browse files
Merge pull request #4 from hammerstonedev/af-additions
Add a few features
2 parents b6a9cdb + 230e85f commit 417860a

File tree

4 files changed

+124
-16
lines changed

4 files changed

+124
-16
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ vendor
1010
node_modules
1111

1212
docs/*.blade.php
13-
docs/**/*.blade.php
13+
docs/**/*.blade.php
14+
.phpunit.cache/test-results

src/Arbiter.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Arbiter
1919

2020
public $totalFailuresAllowed = INF;
2121

22-
public $throw = true;
22+
public $handleFailuresWith;
2323

2424
protected $key;
2525

@@ -41,10 +41,20 @@ public function __construct($id)
4141
$this->totalFailures = Arr::get($stats, 'total', 0);
4242
$this->consecutiveFailures = Arr::get($stats, 'consecutive', 0);
4343
$this->deadline = Arr::get($stats, 'deadline');
44+
45+
$this->handleFailuresWith = function ($e) {
46+
throw $e;
47+
};
4448
}
4549

46-
public function handle($exception)
50+
public function handle($exception, $bypassProtections = false)
4751
{
52+
if ($bypassProtections) {
53+
$this->callHandler($exception);
54+
55+
return;
56+
}
57+
4858
$this->deadline = $this->deadline ?? $this->freshDeadline();
4959

5060
if ($exception) {
@@ -55,10 +65,15 @@ public function handle($exception)
5565
$this->updateCachedStats($exception);
5666

5767
if ($this->outOfBounds() && !is_null($exception)) {
58-
$this->throw ? throw $exception : report($exception);
68+
$this->callHandler($exception);
5969
}
6070
}
6171

72+
public function handleFailures($callback)
73+
{
74+
$this->handleFailuresWith = $callback;
75+
}
76+
6277
public function outOfBounds()
6378
{
6479
return $this->tooManyConsecutiveFailures() || $this->tooManyTotalFailures() || $this->beyondDeadline();
@@ -79,6 +94,11 @@ public function beyondDeadline()
7994
return now()->timestamp > $this->deadline;
8095
}
8196

97+
protected function callHandler($exception)
98+
{
99+
call_user_func($this->handleFailuresWith, $exception);
100+
}
101+
82102
protected function freshDeadline()
83103
{
84104
return now()->addSeconds($this->failuresAllowedForSeconds)->timestamp;

src/Flaky.php

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,38 @@ public function __construct($id)
4545

4646
public function run(callable $callable)
4747
{
48-
$failed = false;
4948
$exception = null;
5049
$value = null;
5150

5251
try {
5352
$value = retry($this->retry['times'], $callable, $this->retry['sleep'], $this->retry['when']);
5453
} catch (Throwable $e) {
55-
$failed = true;
5654
$exception = $e;
5755
}
5856

59-
if ($this->protectionsBypassed() && $failed) {
60-
throw $exception;
61-
}
62-
63-
$this->arbiter->handle($exception);
57+
$this->arbiter->handle($exception, $this->protectionsBypassed());
6458

6559
return new Result($value, $exception);
6660
}
6761

62+
public function handle(Throwable $exception = null)
63+
{
64+
return $this->run(function () use ($exception) {
65+
if (!is_null($exception)) {
66+
throw $exception;
67+
}
68+
});
69+
}
70+
71+
public function disableLocally()
72+
{
73+
if (app()->environment('local')) {
74+
$this->disableFlakyProtection();
75+
}
76+
77+
return $this;
78+
}
79+
6880
public function disableFlakyProtection($disabled = true)
6981
{
7082
$this->flakyProtectionDisabled = $disabled;
@@ -84,18 +96,25 @@ public function retry($times = 0, $sleepMilliseconds = 0, $when = null)
8496
return $this;
8597
}
8698

87-
public function reportFailures()
99+
public function handleFailures($callback)
88100
{
89-
$this->arbiter->throw = false;
101+
$this->arbiter->handleFailures($callback);
90102

91103
return $this;
92104
}
93105

94-
public function throwFailures()
106+
public function reportFailures()
95107
{
96-
$this->arbiter->throw = true;
108+
return $this->handleFailures(function ($e) {
109+
report($e);
110+
});
111+
}
97112

98-
return $this;
113+
public function throwFailures()
114+
{
115+
return $this->handleFailures(function ($e) {
116+
throw $e;
117+
});
99118
}
100119

101120
public function allowFailuresFor($seconds = 0, $minutes = 0, $hours = 0, $days = 0)

tests/Unit/BasicTest.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,72 @@ public function report(Throwable $e)
117117
$this->assertNotNull($handler->reported);
118118
$this->assertInstanceOf(Exception::class, $handler->reported);
119119
}
120+
121+
/** @test */
122+
public function can_disable()
123+
{
124+
$this->expectException(Exception::class);
125+
$this->expectExceptionMessage('Oops');
126+
127+
Flaky::make(__FUNCTION__)
128+
->allowFailuresForADay()
129+
->disableFlakyProtection()
130+
->run(function () {
131+
throw new Exception('Oops');
132+
});
133+
134+
config(['app.env' => 'production']);
135+
}
136+
137+
/** @test */
138+
public function can_disable_locally()
139+
{
140+
Flaky::make(__FUNCTION__)
141+
->allowFailuresForADay()
142+
->run(function () {
143+
throw new Exception('Oops');
144+
});
145+
146+
$this->app->detectEnvironment(function () {
147+
return 'local';
148+
});
149+
150+
$this->expectException(Exception::class);
151+
$this->expectExceptionMessage('Oops');
152+
153+
Flaky::make(__FUNCTION__)
154+
->allowFailuresForADay()
155+
->disableLocally()
156+
->run(function () {
157+
throw new Exception('Oops');
158+
});
159+
}
160+
161+
/** @test */
162+
public function can_handle_failures_ourselves()
163+
{
164+
$caught = null;
165+
$handled = false;
166+
167+
Flaky::make(__FUNCTION__)
168+
->allowConsecutiveFailures(0)
169+
->handleFailures(function ($e) use (&$caught, &$handled) {
170+
$caught = $e;
171+
$handled = true;
172+
})
173+
->run(function () {
174+
throw new Exception('Oops');
175+
});
176+
177+
$this->assertTrue($handled);
178+
$this->assertInstanceOf(Exception::class, $caught);
179+
}
180+
181+
/** @test */
182+
public function can_pass_in_our_own_exception()
183+
{
184+
$result = Flaky::make(__FUNCTION__)->handle(new Exception('Oops'));
185+
186+
$this->assertInstanceOf(Result::class, $result);
187+
}
120188
}

0 commit comments

Comments
 (0)