▶Pipeline running — orders-daily · Batch 1 / 10
0 rows/sec · 0 total processed
⚡ Pipeline Data Flow — Live
Watching data move from S3 → Redshift in real time
Rows Extracted
0
from S3
Rows Loaded ✓
0
to Redshift
Rows Rejected ✗
0
to DLQ
Success Rate
—
this run
📦 Current Batch
Initializing…
Batch progress 0 / 0
Rows in batch —
Format —
Throughput —
Retry attempts 0
🗄️ Source Files
S3 prefix scan
Source bucket —
Files discovered —
📋 Run History
0 runs total
No completed runs yet.
🚫 Dead Letter Queue
No rejected rows yet.
Python Backend
The ETL engine behind this demo
src/pipeline.py — orchestrator with retry + DLQ
class DataForgePipeline:
    """Flow: S3 raw files → Extract → Validate/Transform → Load (Redshift) → DLQ"""

    def run(self) -> RunStats:
        stats, started = RunStats(), time.monotonic()

        for idx, batch in enumerate(self.extractor.extract(batch_size=self.config.batch_size)):
            stats.batches_total  += 1
            stats.rows_extracted += len(batch)
            try:
                clean, rejected = self.transformer.transform(batch)  # validate + coerce
                stats.rows_rejected += len(rejected)

                if rejected:
                    self._send_to_dlq(rejected, reason="validation_failure")

                with_retry(                          # exponential backoff
                    lambda: self.loader.load(clean),
                    max_attempts=self.config.max_retries,
                )
                stats.rows_loaded += len(clean)

            except Exception as exc:
                stats.batches_failed += 1
                self._send_to_dlq(batch, reason=exc)   # whole batch → DLQ

        stats.duration_sec = time.monotonic() - started
        return stats   # rows_extracted, loaded, rejected, success_rate, duration