GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - Lalithsha/ReHook: Enterprise-grade, high-throughput Webhook Delivery Engine with atomic Redlock execution, exponential jitter backoff, Redis 3-state circuit breaking, dual-secret rotation, and DLQ replay.

BranchesTags
Open more actions menu

Latest commit

 

History

32 Commits
32 Commits

Folders and files

NameName
Last commit message
Last commit date
.github/workflows
.github/workflows
 
 
apps
apps
 
 
brag-output
brag-output
 
 
demo-output
demo-output
 
 
docs
docs
 
 
load-tests
load-tests
 
 
packages
packages
 
 
.dockerignore
.dockerignore
 
 
.gitignore
.gitignore
 
 
.npmrc
.npmrc
 
 
README.md
README.md
 
 
bun.lock
bun.lock
 
 
docker-compose.yml
docker-compose.yml
 
 
gemini.md
gemini.md
 
 
package.json
package.json
 
 
turbo.json
turbo.json
 
 

Repository files navigation

ReHook — Keep business events moving. Automatic retries, visible failures, and a path to recovery.

ReHook · Webhook delivery & recovery

When one service goes down, important events should still have a path forward.

ReHook is a backend platform and operator dashboard that sends events between applications, retries failed deliveries, and lets an operator inspect and replay events that need attention. Think of an online store sending an “order paid” notification to a fulfillment service: if the receiver is unavailable, ReHook tracks what happened and provides a way to recover.

Built with TypeScript, Bun, Express, PostgreSQL, Redis, BullMQ, and Next.js.

CI

See the product · Results & evidence · How it works · Run locally · Technical handbook

Why this matters

A webhook is an HTTP notification from one application to another. A successful checkout, account update, or shipment can trigger one. Networks fail and receiving services go offline—so sending a request once is rarely enough.

When this happens… ReHook provides… Why it helps
A receiver fails or times out Automatic retries with increasing, randomized delays Temporary outages can recover without someone resending every event
An endpoint keeps failing A shared circuit breaker that pauses outbound requests Workers stop repeatedly calling a known failing destination
The retry budget runs out A dead-letter queue: a visible list of events needing attention Operators can inspect the failure and replay the event after fixing the cause
A signing secret needs changing Signatures with both the existing and new key during rotation Receivers can transition keys while continuing to verify events
The database accepts an event but the queue is unavailable A transactional outbox that retains work awaiting publication Accepted events have a durable scheduling record in PostgreSQL

See the product

One screen to understand delivery health

The operator dashboard shows delivery status, events still in progress, and events waiting for recovery. Each event has a payload and attempt history to explain its journey.

ReHook dashboard after the recorded recovery demo: nine events delivered, no retries in flight, and no events left in the dead-letter queue.

Real application capture from the local demo. The nine-event result describes this recorded run.

Watch the complete workflow · 2 min 18 sec

Register a receiver → send an event → simulate failure → inspect retries → replay → rotate keys → recover from an outage.

rehook-full-demo.mp4
Jump to a specific capability
Time What to look for
00:06 Register a receiver and its signing secret
00:17 Dispatch an event and inspect signed delivery
00:42 Simulate HTTP 500 errors and observe automatic retries
01:07 Inspect the dead-letter queue and replay a failed event
01:25 Rotate a secret and verify both signatures
01:44 Simulate an outage and observe circuit-open suppression
01:57 Restore the receiver and replay the outage events
02:12 Final recap
Short on time? Watch the 20-second architecture showcase

A brief introduction to the delivery engine, local benchmark, and resilience features. Measurement context is explained below.

brag.mp4

Results & evidence

The impact demonstrated here is recoverability, visibility, and controlled delivery under failure. These are local engineering results, not customer adoption or production service guarantees.

Achievement Evidence What it establishes
9 of 9 demo events delivered; 0 left dead Recorded demo evidence and dashboard above Failed events were inspectable and recovered through replay after the receiver returned
Both signing keys verified successfully Receiver response reports v1: true, v2: true, HTTP 200 Dual-key signing worked for a newly submitted event during rotation
An open circuit suppressed an HTTP call Attempt history records circuit_open with no HTTP status, followed by HTTP 200 after recovery The recorded outage exercised request suppression and recovery
769 accepted requests/sec in a local burst Published benchmark: 1,000 requests, concurrency 50, 1.30 sec; all returned success Historical API ingestion performance on the documented local environment
95 of 100 simulated checks blocked Circuit-breaker exercise: record five failures, then check 95 more decisions State-based suppression in a Redis-backed simulation

Measurement context: The throughput report predates the current transactional-outbox changes and should be rerun to measure the current version. It measures API acceptance, not end-to-end delivery. The 95% circuit result comes from a simulation; that script does not send 100 real HTTP requests. Benchmark methodology and reported latency.

Built for the moments that go wrong

Failures stay explainable

A failed event retains its original payload and attempt history. The operator can see the HTTP response, elapsed time, and delivery identifier, then replay a dead event after addressing the underlying problem.

Actual ReHook attempt inspector showing a dead payment.failed event, three exhausted attempts, an HTTP 500 response, and the replay control.

In the demo, a three-attempt budget was exhausted before the event was replayed successfully.

See proof of signing-key rotation

Actual ReHook attempt inspector showing HTTP 200 and a receiver response that verifies both v1 and v2 signatures.

The receiver confirmed both HMAC-SHA256 signatures on a new event after rotation. The overlap lets receivers adopt the new key while the previous key remains available.

How it works

Accept and store first. Deliver in the background. Keep a record of every attempt.

ReHook event journey: receive and validate, store the event and outbox, queue background work, and deliver securely. Successful requests are marked delivered; failures retry and exhausted events can be inspected and replayed.

Read the numbered path first: Receive → Store → Queue → Deliver. A successful delivery is recorded. Failures take the recovery branch: retry automatically, or inspect the dead-letter queue and replay after fixing the cause. Manual replay schedules a fresh delivery immediately.

Technical architecture — components, persistence, and recovery paths
flowchart TD
    APP["Application sends an event"] --> API["API: authenticate & validate"]
    API -->|Atomic write| TX["PostgreSQL<br/>Events + outbox records"]
    TX --> RELAY["Outbox relay"]
    RELAY --> Q["Redis / BullMQ"]
    Q --> W["Worker<br/>Lock + state claim"]
    W --> CB{"Circuit allows delivery?"}
    CB -->|Yes| SEND["Sign payload & send HTTP"]
    SEND --> REC["Receiving application"]
    REC -->|Success| OK["Mark delivered"]
    REC -->|Failure or timeout| RETRY["Schedule retry or mark dead"]
    CB -->|No| RETRY
    RETRY -->|State + next outbox record| TX
    W -.-> AUDIT["PostgreSQL attempt history"]
    AUDIT -.-> UI["Next.js dashboard<br/>Inspect & replay"]
    UI -->|Replay dead event| API
Loading

An outbox is a database record of work waiting to be sent to the queue. ReHook creates it in the same transaction as the event. The relay retries publication when Redis is available; the request path does not wait for the receiving application.

Engineering decisions worth exploring

Decision Implementation Tradeoff / purpose
Durable handoff Transactional event + outbox creation, relay Adds a database write and polling delay to retain work across queue-publication failures
Coordinate workers Redis lease with renewal and ownership-checked Lua release, conditional database claim Reduces concurrent duplicate execution; does not create an exactly-once guarantee
Back off under failure Exponential jitter, host-based circuit state Spreads retry timing and pauses failing hosts; open-circuit evaluations can consume the attempt budget
Preserve event identity Stable event ID and separate delivery IDs Receivers can deduplicate business events and correlate individual attempts
Authenticate and isolate Project-scoped API authentication, target URL checks Scopes data access and restricts private/reserved targets in production mode
Make failures observable Delivery/outbox/queue metrics, worker metrics and shutdown Exposes operational state and drains active jobs during normal shutdown

Delivery semantics: The design targets at-least-once delivery with a bounded attempt budget and operator replay. Receivers should deduplicate using X-ReHook-Event-ID; a retry can repeat an HTTP request. Multi-node Redlock and exactly-once delivery are not implemented guarantees.

Next engineering steps: Recover events stranded in processing after a worker crash, add atomic ownership of half-open circuit probes, replace browser-visible development API keys with server-side authentication, and rerun failure/load tests against the current implementation. Hardening plan.

Technology & project structure

Layer Technologies Responsibility
API TypeScript · Bun · Express · Zod Authentication, validation, event ingestion, inspection, replay
Persistence PostgreSQL · Prisma Events, endpoint keys, attempt history, transactional outbox
Queue & workers Redis · BullMQ Background delivery, scheduling, concurrency coordination
Operator UI Next.js · React · Tailwind CSS Delivery dashboard, failure inspection, endpoint management
Operations Docker Compose · Prometheus metrics · GitHub Actions Local environment, observability, automated checks
apps/api/       API, delivery workers, Prisma schema & migrations
apps/web/       Operator dashboard
packages/       Shared UI and TypeScript/ESLint configuration
load-tests/     Native and k6 benchmark scripts
docs/           Architecture, benchmarks, visual assets & demo evidence
demo-output/    Recorded full product walkthrough
brag-output/    Short architecture showcase

Run locally

Prerequisites: Docker with Docker Compose. The Compose setup runs PostgreSQL, Redis, the API, delivery workers, and the dashboard.

git clone https://github.com/Lalithsha/ReHook.git
cd ReHook
docker compose up --build -d
Service Local address
Operator dashboard http://localhost:3000
API liveness / dependency readiness http://localhost:3001/api/health · http://localhost:3001/api/ready
API summary metrics http://localhost:3001/api/v1/metrics
Worker Prometheus metrics http://localhost:9464/metrics

The Compose file includes development credentials and allows local/private receiver URLs for testing. It is configured for local development.

Try a delivery against the included mock receiver

With Bun installed, start the receiver on your host in a separate terminal:

bun install
bun mock:receiver

Submit an event to the Dockerized API. Docker Desktop on macOS/Windows can reach the host receiver through host.docker.internal:

curl -X POST http://localhost:3001/api/v1/webhooks \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: super_secret_rehook_key_123' \
  -d '{
    "target_url": "http://host.docker.internal:4000/webhook",
    "event_type": "order.paid",
    "payload": {"order_id": "demo-001", "amount": 49.99},
    "retry_config": {"max_attempts": 3, "initial_delay_ms": 1000}
  }'

The API returns 202 Accepted with the event ID. Look for it in the dashboard; delivery happens asynchronously. To exercise failure handling, submit another event with ?mode=fail appended to the receiver URL. On Linux, configure the Docker host gateway or use a receiver reachable from the worker container.

Run API tests with local PostgreSQL and Redis

With Bun installed and Compose running:

bun install
cp apps/api/.env.example apps/api/.env
bun db:generate
bun test:api

Adjust the copied environment file if your local ports or credentials differ. Prisma client generation is required after schema changes. Test files cover authentication, validation, signatures, backoff, locks, circuit breaking, and worker/API behavior. The live CI badge above links to current results.

API at a glance

Protected routes use x-api-key; project-scoped clients can also send x-project-id.

Capability Routes
Send & inspect events POST /api/v1/webhooks · GET /api/v1/webhooks
Delivery status & audit history GET /api/v1/webhooks/:id/status · GET /api/v1/webhooks/:id/attempts
Inspect failed events GET /api/v1/dlq · GET /api/v1/dlq/:id
Replay one dead event POST /api/v1/dlq/:id/replay
Register & list receivers POST /api/v1/endpoints · GET /api/v1/endpoints
Rotate a signing secret POST /api/v1/endpoints/:id/rotate

Route definitions · Request validation

Explore further

  • System handbook — schema, lifecycle, implementation details, and design tradeoffs.
  • Performance report — historical local results and reproduction scripts.
  • Production hardening plan — durability, security, identity, observability, and remaining work.
  • Demo evidence — selected results from the recorded local run.
  • Visual sources — provenance of the real UI captures used here.

Built by Lalith Sharma · Backend systems, reliability, and full stack product engineering.

About

Enterprise-grade, high-throughput Webhook Delivery Engine with atomic Redlock execution, exponential jitter backoff, Redis 3-state circuit breaking, dual-secret rotation, and DLQ replay.

Topics

bullmqbuncircuit-breakerdlqevent-drivenexpresspostgresqlredisredlocktypescriptwebhookwebhook-engine

Resources

Readme
Activity

Stars

0 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.