mail: zentrale Bounce-Suppression mit Versand-Gate und Circuit Breaker (Roadmap 1b.6, Schritte 1–2)
email_suppressions/email_bounces als Zustand und Ereignis-Log; ein MessageSending-Listener streicht gesperrte Empfänger aus JEDER ausgehenden Mail und setzt den Return-Path. Zweiter Aufnahmepfad: SMTP-Ablehnungen im Worker — 5.1.x sperrt den Empfänger, Relay-Ablehnungen zählen für den Circuit Breaker, der den Versand anhält statt gesunde Adressen zu sperren. X-Pk-Ref-Header auf den Mails, API-Meldungen fallen auf die Firmen-E-Mail zurück, der Bounce-Import schreibt in die zentrale Liste. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
85b039e739
commit
8bf40ee37e
25 changed files with 1312 additions and 4 deletions
36
app/Console/Commands/MailCircuitCommand.php
Normal file
36
app/Console/Commands/MailCircuitCommand.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Mail\MailCircuitBreaker;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Zustand des Mail-Circuit-Breakers anzeigen oder die Pause aufheben.
|
||||
*/
|
||||
class MailCircuitCommand extends Command
|
||||
{
|
||||
protected $signature = 'mail:circuit {--reset : Pause aufheben und Zähler zurücksetzen}';
|
||||
|
||||
protected $description = 'Zeigt, ob der Mailversand angehalten ist (Circuit Breaker), und hebt die Pause auf Wunsch auf.';
|
||||
|
||||
public function handle(MailCircuitBreaker $breaker): int
|
||||
{
|
||||
if ($this->option('reset')) {
|
||||
$breaker->reset();
|
||||
$this->info('Circuit Breaker zurückgesetzt — der Versand läuft wieder. Liegengebliebene Mails: php artisan queue:retry all');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$until = $breaker->openUntil();
|
||||
|
||||
if ($until !== null) {
|
||||
$this->warn(sprintf('Versand ANGEHALTEN bis %s.', $until->format('d.m.Y H:i')));
|
||||
} else {
|
||||
$this->info(sprintf('Versand läuft. Relay-Ablehnungen im aktuellen Fenster: %d.', $breaker->pendingRejections()));
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue