1. Go to this page and download the library: Download harris21/laravel-fuse library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
harris21 / laravel-fuse example snippets
use Harris21\Fuse\Middleware\CircuitBreakerMiddleware;
class ChargeCustomer implements ShouldQueue
{
public $tries = 0; // Unlimited releases
public $maxExceptions = 3; // Unhandled exceptions before the job fails
public function middleware(): array
{
return [new CircuitBreakerMiddleware('stripe', release: 20)];
}
public function handle(): void
{
// Your payment logic - unchanged
Stripe::charges()->create([...]);
}
}
use Harris21\Fuse\Attributes\UseCircuitBreaker;
use Harris21\Fuse\Middleware\ResolvesCircuitBreakers;
#[UseCircuitBreaker('stripe')]
class ChargeCustomer implements ShouldQueue
{
public function middleware(): array
{
return ResolvesCircuitBreakers::resolve($this);
}
}
#[UseCircuitBreaker('stripe')]
#[UseCircuitBreaker('mailgun', release: 30)]
class ChargeAndNotify implements ShouldQueue
{
public function middleware(): array
{
return ResolvesCircuitBreakers::resolve($this);
}
}
namespace App\Fuse;
use GuzzleHttp\Exception\ServerException;
use Harris21\Fuse\Classifiers\DefaultFailureClassifier;
use Throwable;
class StripeFailureClassifier extends DefaultFailureClassifier
{
public function shouldCount(Throwable $e): bool
{
// Stripe returns 500 for idempotency errors — not a real outage
if ($e instanceof ServerException) {
$body = (string) $e->getResponse()?->getBody();
if (str_contains($body, 'idempotency')) {
return false;
}
}
return parent::shouldCount($e);
}
}
namespace App\Fuse;
use Harris21\Fuse\Contracts\FailureClassifier;
use Throwable;
class CustomFailureClassifier implements FailureClassifier
{
public function shouldCount(Throwable $e): bool
{
// Your classification logic
}
}
namespace App\Jobs\Middleware;
use Illuminate\Http\Client\RequestException;
class ReleasesRateLimitedJobs
{
public function handle(mixed $job, callable $next): mixed
{
try {
return $next($job);
} catch (RequestException $e) {
if ($e->response->status() === 429) {
$delay = (int) $e->response->header('Retry-After') ?: 30;
return $job->release($delay);
}
throw $e;
}
}
}
public function middleware(): array
{
return [
new ReleasesRateLimitedJobs,
new CircuitBreakerMiddleware('stripe'),
];
}
namespace App\Fuse;
use Harris21\Fuse\CircuitBreaker;
use Harris21\Fuse\Contracts\RecoveryStrategy;
class CustomRecoveryStrategy implements RecoveryStrategy
{
public function allowsAttempt(CircuitBreaker $breaker): bool
{
// Return true to let this half-open job through, false to release it for a later retry.
}
public function recordSuccess(CircuitBreaker $breaker): bool
{
// Return true to fully close the circuit, false to keep testing.
}
public function recordFailure(CircuitBreaker $breaker): void
{
// Called when a half-open job fails. The circuit reopens around this call.
}
}
use Harris21\Fuse\Events\CircuitBreakerOpened;
use Harris21\Fuse\Events\CircuitBreakerHalfOpen;
use Harris21\Fuse\Events\CircuitBreakerClosed;
// app/Listeners/AlertOnCircuitOpen.php
class AlertOnCircuitOpen
{
public function handle(CircuitBreakerOpened $event): void
{
Log::critical("Circuit breaker opened for {$event->service}", [
'failure_rate' => $event->failureRate,
'attempts' => $event->attempts,
'failures' => $event->failures,
]);
// Send Slack notification, page on-call, etc.
}
}
class NotifySlackOnCircuitOpen
{
public function handle(CircuitBreakerOpened $event): void
{
Http::post(config('services.slack.webhook_url'), [
'text' => sprintf(
':rotating_light: Circuit breaker OPEN for *%s* — %.1f%% failure rate (%d/%d requests)',
$event->service,
$event->failureRate,
$event->failures,
$event->attempts,
),
]);
}
}
class RecordCircuitBreakerMetrics
{
public function __construct(private CollectorRegistry $registry) {}
private function gauge(): \Prometheus\Gauge
{
return $this->registry->getOrRegisterGauge(
'fuse', 'circuit_open', 'Circuit breaker state (1 = open, 0 = closed)', ['service']
);
}
public function handleOpened(CircuitBreakerOpened $event): void
{
$this->gauge()->set(1, [$event->service]);
}
public function handleClosed(CircuitBreakerClosed $event): void
{
$this->gauge()->set(0, [$event->service]);
}
}
namespace App\Recorders;
use Harris21\Fuse\Events\CircuitBreakerOpened;
use Laravel\Pulse\Facades\Pulse;
class CircuitBreakerRecorder
{
public array $listen = [CircuitBreakerOpened::class];
public function record(CircuitBreakerOpened $event): void
{
Pulse::record('fuse_circuit_open', $event->service)->count();
}
}
// config/fuse.php
'services' => [
'stripe' => [
'threshold' => 50, // trip at 50% failure rate
'timeout' => 30, // wait 30s before probing again
'min_requests' => 5, // need at least 5 requests to evaluate
],
],
class ChargeCustomer implements ShouldQueue
{
public $tries = 0;
public $maxExceptions = 3;
public function middleware(): array
{
return [new CircuitBreakerMiddleware('stripe', release: 20)];
}
public function handle(): void
{
Stripe::charges()->create([...]);
}
}
class DeliverWebhook implements ShouldQueue
{
public $tries = 0;
public $maxExceptions = 3;
public function __construct(
private WebhookEndpoint $endpoint,
private array $payload,
) {}
public function middleware(): array
{
return [new CircuitBreakerMiddleware("webhook:{$this->endpoint->id}", release: 30)];
}
public function handle(): void
{
Http::timeout(5)->post($this->endpoint->url, $this->payload)->throw();
}
}
use Illuminate\Support\Facades\Gate;
Gate::define('viewFuse', function ($user = null) {
return $user?->isAdmin();
});
use Harris21\Fuse\CircuitBreaker;
$breaker = new CircuitBreaker('stripe');
if (!$breaker->isOpen()) {
try {
$result = Stripe::charges()->create([...]);
$breaker->recordSuccess();
return $result;
} catch (Exception $e) {
$breaker->recordFailure($e);
throw $e;
}
} else {
// Circuit is open - use fallback
return $this->fallbackResponse();
}
$breaker = new CircuitBreaker('stripe');
$breaker->isClosed(); // Normal operations
$breaker->isOpen(); // Protected, failing fast
$breaker->isHalfOpen(); // Testing recovery
$breaker->getStats(); // Get full statistics
$breaker->reset(); // Manually reset to closed
bash
php artisan vendor:publish --tag=fuse-config
bash
php artisan fuse:open stripe
bash
php artisan fuse:close stripe
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.