From acc
Generates Dead Letter Queue components for PHP 8.4: failed message capture, exponential backoff retry strategy, failure classification, DLQ processor, database store via PDO, and unit tests.
How this skill is triggered — by the user, by Claude, or both
Slash command
/acc:create-dead-letter-queueThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Creates Dead Letter Queue pattern infrastructure for capturing and retrying failed messages.
Creates Dead Letter Queue pattern infrastructure for capturing and retrying failed messages.
| Scenario | Example |
|---|---|
| Poison messages | Messages that always cause handler failures |
| Processing failures | Temporary infrastructure issues (DB down, timeout) |
| Audit trail | Track all failed message processing attempts |
| Retry mechanism | Automatic retry with exponential backoff |
| Monitoring | Alert on DLQ threshold exceeded |
Determine:
Domain Layer (src/Domain/Shared/DeadLetter/)
FailureType.php — Enum (Transient, Permanent, Unknown)DeadLetterMessage.php — Message entityApplication Layer (src/Application/Shared/DeadLetter/)
DeadLetterStoreInterface.php — Storage portDeadLetterHandler.php — Exception handlerRetryStrategy.php — Retry configuration and backoff calculationFailureClassifier.php — Exception classificationDlqProcessor.php — Retry processorInfrastructure Layer (src/Infrastructure/DeadLetter/)
DatabaseDeadLetterStore.php — PDO implementationTests
DeadLetterMessageTest.phpRetryStrategyTest.phpFailureClassifierTest.phpDlqProcessorTest.php| Layer | Path |
|---|---|
| Domain Types | src/Domain/Shared/DeadLetter/ |
| Application | src/Application/Shared/DeadLetter/ |
| Infrastructure | src/Infrastructure/DeadLetter/ |
| Unit Tests | tests/Unit/{Layer}/{Path}/ |
Message → Handler fails → DeadLetterHandler → Store to DLQ
↓
DlqProcessor retries
↓
Success → Remove from DLQ
Failure → Re-store with incremented attempts
Max exceeded → Mark as permanently failed
| Component | Pattern | Example |
|---|---|---|
| Failure Enum | FailureType | FailureType |
| Message Entity | DeadLetterMessage | DeadLetterMessage |
| Store Interface | DeadLetterStoreInterface | DeadLetterStoreInterface |
| Handler | DeadLetterHandler | DeadLetterHandler |
| Strategy | RetryStrategy | RetryStrategy |
| Classifier | FailureClassifier | FailureClassifier |
| Processor | DlqProcessor | DlqProcessor |
| Test | {ClassName}Test | RetryStrategyTest |
final class DeadLetterMessage
{
public function __construct(
public readonly string $id,
public readonly string $originalBody,
public readonly string $originalRoutingKey,
public readonly array $originalHeaders,
public readonly string $errorMessage,
public readonly string $errorTrace,
public readonly FailureType $failureType,
public readonly int $attemptCount,
public readonly \DateTimeImmutable $failedAt,
public readonly ?\DateTimeImmutable $nextRetryAt,
public readonly ?\DateTimeImmutable $resolvedAt = null,
) {}
public function isRetryable(int $maxAttempts): bool;
public function withIncrementedAttempt(\DateTimeImmutable $nextRetryAt): self;
}
interface DeadLetterStoreInterface
{
public function store(DeadLetterMessage $message): void;
/** @return array<DeadLetterMessage> */
public function findRetryable(int $limit = 100): array;
public function markRetried(string $id, \DateTimeImmutable $nextRetryAt): void;
public function markResolved(string $id): void;
public function purge(\DateTimeImmutable $before): int;
public function countByType(FailureType $type): int;
}
CREATE TABLE dead_letter_messages (
id VARCHAR(255) PRIMARY KEY,
original_body TEXT NOT NULL,
original_routing_key VARCHAR(255) NOT NULL,
original_headers JSONB NOT NULL DEFAULT '{}',
error_message TEXT NOT NULL,
error_trace TEXT,
failure_type VARCHAR(50) NOT NULL,
attempt_count INTEGER NOT NULL DEFAULT 1,
failed_at TIMESTAMP(6) NOT NULL,
next_retry_at TIMESTAMP(6),
resolved_at TIMESTAMP(6)
);
CREATE INDEX idx_dlq_retryable ON dead_letter_messages (failure_type, next_retry_at)
WHERE resolved_at IS NULL AND failure_type != 'permanent';
CREATE INDEX idx_dlq_failed_at ON dead_letter_messages (failed_at);
For complete PHP templates and test examples, see:
references/templates.md — All component templatesreferences/examples.md — Message broker integration example and unit testsnpx claudepluginhub dykyi-roman/awesome-claude-code --plugin accHandles permanently failing messages with dead letter queues for safe inspection, alerting, and reprocessing. Includes TypeScript implementation of a DLQ class with reprocessing and alerting.
Generates Transactional Outbox pattern components for PHP 8.4: OutboxMessage entity, repository interface and impl, publisher ports, processor service, console command, Doctrine migration, and unit tests. For reliable event publishing across transactions.
Guides message queue and job processing setup with Kafka, RabbitMQ, SQS, BullMQ, Celery, Sidekiq. Covers architecture, retries, DLQs, idempotency, priorities, backpressure, and scaling.