Skip to content

Commit 1412896

Browse files
committed
feat! retry mechanism
1 parent 96e3e99 commit 1412896

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

.ci/build-version.php

100644100755
File mode changed.

app/Commands/Compare/CompareSitemapAToWebsiteB.php

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

33
namespace App\Commands\Compare;
44

5+
use App\Service\RetryService;
56
use Illuminate\Console\Command;
67
use Spatie\Fork\Fork;
78

@@ -73,7 +74,17 @@ public function handle(): void
7374
$forkArray = [];
7475
foreach ($sitemapUrls as $url) {
7576
$forkArray[] = function () use ($url) {
76-
return $this->checkUrl($url);
77+
/**
78+
* Retry mechanism to handle errors gracefully instead of just killing the whole process
79+
* if one URL fails.
80+
*/
81+
return RetryService::Retry(
82+
3,
83+
fn () => $this->checkUrl($url),
84+
500,
85+
fn ($exception) => $this->warn("[Retry] Error checking URL $url: ".$exception->getMessage()),
86+
fn ($exception) => $this->warn("[Retry] Failed to check URL $url after multiple attempts: ".$exception->getMessage())
87+
);
7788
};
7889
}
7990

@@ -83,8 +94,13 @@ public function handle(): void
8394
->run(...$forkArray);
8495

8596
foreach ($outputs as $output) {
86-
if ($output['is_successful']) {
87-
$foundUrls[] = $output['url'];
97+
try {
98+
if ($output['is_successful']) {
99+
$foundUrls[] = $output['url'];
100+
}
101+
// @phpstan-ignore-next-line
102+
} catch (\Throwable $exception) {
103+
$this->warn('Unknown output from output array: '.json_encode($output));
88104
}
89105
}
90106

@@ -106,7 +122,7 @@ public function handle(): void
106122
private function outputCli(
107123
array $sitemapUrls,
108124
array $foundUrls
109-
) {
125+
): void {
110126
$this->info('Sitemap URLs from source1:');
111127
foreach ($sitemapUrls as $url) {
112128
$this->line($url);
@@ -132,7 +148,7 @@ private function outputCli(
132148
private function outputJson(
133149
array $sitemapUrls,
134150
array $foundUrls
135-
) {
151+
): void {
136152

137153
$urlsNotFound = array_values(array_diff($sitemapUrls, $foundUrls));
138154
$output = [

app/Service/RetryService.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App\Service;
4+
5+
class RetryService
6+
{
7+
/**
8+
* Retry a callable function a specified number of times with optional sleep and error handling.
9+
*
10+
* @param int $times how many times to retry
11+
* @param callable $callback the function to execute
12+
* @param int $sleep milliseconds to wait between retries
13+
* @param callable|null $onError function to call on each error
14+
* @param callable|null $onFail function to call if all retries fail
15+
* @return mixed the result of the callback
16+
*
17+
* @throws \Exception if all retries fail and no onFail is provided
18+
*/
19+
public static function Retry(
20+
int $times,
21+
callable $callback,
22+
int $sleep = 0,
23+
?callable $onError = null,
24+
?callable $onFail = null
25+
): mixed {
26+
$attempts = 0;
27+
beginning:
28+
$attempts++;
29+
try {
30+
return $callback($attempts);
31+
} catch (\Exception $e) {
32+
if ($attempts >= $times) {
33+
if ($onFail) {
34+
$onFail($e, $attempts);
35+
36+
return null;
37+
}
38+
39+
throw $e;
40+
}
41+
if ($onError) {
42+
$onError($e, $attempts);
43+
}
44+
if ($sleep > 0) {
45+
usleep($sleep * 1000); // Convert milliseconds to microseconds
46+
}
47+
goto beginning;
48+
}
49+
50+
return null; // Yes, I know this is unreachable, but phpstan complains without it
51+
}
52+
}

builds/sitemap-compare

-85 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)