feat: HealthCheckable interface on DaemonRpc and WalletRpc
Services implement healthCheck() returning {status, detail, stale?}.
Status page refactored to use healthCheck() instead of ad-hoc checks.
Statuses: healthy, degraded (stale data), unhealthy (unreachable).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
924e8e223f
commit
b4e4766e01
4 changed files with 65 additions and 16 deletions
19
app/Mod/Chain/Contracts/HealthCheckable.php
Normal file
19
app/Mod/Chain/Contracts/HealthCheckable.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mod\Chain\Contracts;
|
||||
|
||||
/**
|
||||
* Service health check interface.
|
||||
*
|
||||
* $result = $service->healthCheck();
|
||||
* if ($result['status'] === 'healthy') { ... }
|
||||
*/
|
||||
interface HealthCheckable
|
||||
{
|
||||
/**
|
||||
* @return array{status: string, detail: string, stale?: bool}
|
||||
*/
|
||||
public function healthCheck(): array;
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ use Illuminate\Support\Facades\Http;
|
|||
* $info = $rpc->getInfo();
|
||||
* $block = $rpc->getBlockByHeight(12345);
|
||||
*/
|
||||
class DaemonRpc implements \Mod\Chain\Contracts\ChainDaemon
|
||||
class DaemonRpc implements \Mod\Chain\Contracts\ChainDaemon, \Mod\Chain\Contracts\HealthCheckable
|
||||
{
|
||||
private string $endpoint;
|
||||
private int $cacheTtl;
|
||||
|
|
@ -154,4 +154,26 @@ class DaemonRpc implements \Mod\Chain\Contracts\ChainDaemon
|
|||
return ['error' => 'Daemon unreachable', '_offline' => true];
|
||||
}
|
||||
}
|
||||
|
||||
public function healthCheck(): array
|
||||
{
|
||||
$info = $this->getInfo();
|
||||
|
||||
if (isset($info['_offline'])) {
|
||||
return ['status' => 'unhealthy', 'detail' => 'Unreachable'];
|
||||
}
|
||||
|
||||
if (isset($info['_stale'])) {
|
||||
return [
|
||||
'status' => 'degraded',
|
||||
'detail' => 'Stale data — height ' . number_format($info['height'] ?? 0),
|
||||
'stale' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => 'healthy',
|
||||
'detail' => 'Height ' . number_format($info['height'] ?? 0) . ' — ' . ($info['status'] ?? 'OK'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Http;
|
|||
* $wallet = app(WalletRpc::class);
|
||||
* $wallet->registerAlias('myname', $address, 'v=lthn1;type=user');
|
||||
*/
|
||||
class WalletRpc implements \Mod\Chain\Contracts\ChainWallet
|
||||
class WalletRpc implements \Mod\Chain\Contracts\ChainWallet, \Mod\Chain\Contracts\HealthCheckable
|
||||
{
|
||||
private string $endpoint;
|
||||
|
||||
|
|
@ -99,4 +99,19 @@ class WalletRpc implements \Mod\Chain\Contracts\ChainWallet
|
|||
|
||||
return $data['result'] ?? $data['error'] ?? [];
|
||||
}
|
||||
|
||||
public function healthCheck(): array
|
||||
{
|
||||
try {
|
||||
$balance = $this->getBalance();
|
||||
|
||||
if (isset($balance['error'])) {
|
||||
return ['status' => 'unhealthy', 'detail' => 'Unreachable'];
|
||||
}
|
||||
|
||||
return ['status' => 'healthy', 'detail' => 'Connected'];
|
||||
} catch (\Throwable $e) {
|
||||
return ['status' => 'unhealthy', 'detail' => 'Unreachable'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,29 +159,22 @@ class HomeController extends Controller
|
|||
public function status(): \Illuminate\View\View
|
||||
{
|
||||
$chainInfo = $this->rpc->getInfo();
|
||||
try {
|
||||
$walletInfo = $this->wallet->getBalance();
|
||||
} catch (\Throwable $e) {
|
||||
$walletInfo = ['error' => 'Wallet unreachable'];
|
||||
}
|
||||
$chainHealth = $this->rpc->healthCheck();
|
||||
$walletHealth = $this->wallet->healthCheck();
|
||||
$liveGateways = $this->registry->liveGateways();
|
||||
$pendingClaims = \Mod\Names\Models\NameClaim::pending()->count();
|
||||
|
||||
$checks = [
|
||||
'chain' => [
|
||||
'label' => 'Blockchain Daemon',
|
||||
'ok' => ! isset($chainInfo['_offline']),
|
||||
'stale' => isset($chainInfo['_stale']),
|
||||
'detail' => isset($chainInfo['_offline'])
|
||||
? 'Unreachable'
|
||||
: 'Height ' . number_format($chainInfo['height'] ?? 0) . ' — ' . ($chainInfo['status'] ?? 'unknown'),
|
||||
'ok' => $chainHealth['status'] !== 'unhealthy',
|
||||
'stale' => $chainHealth['stale'] ?? false,
|
||||
'detail' => $chainHealth['detail'],
|
||||
],
|
||||
'wallet' => [
|
||||
'label' => 'Registry Wallet',
|
||||
'ok' => ! isset($walletInfo['error']),
|
||||
'detail' => isset($walletInfo['error'])
|
||||
? 'Unreachable'
|
||||
: 'Connected',
|
||||
'ok' => $walletHealth['status'] === 'healthy',
|
||||
'detail' => $walletHealth['detail'],
|
||||
],
|
||||
'gateways' => [
|
||||
'label' => 'Paired Gateways',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue