Memproses analitik riwayat Git commit secara massal menggunakan Large Language Model (LLM) sering kali memicu pemborosan token dan kegagalan rate-limit. Saat push berskala besar terjadi di banyak repositori secara bersamaan, sistem background worker rentan memproses duplikasi commit yang sama dari merge branch atau rebase. Artikel ini merancang pipeline ringkasan Git commit yang efisien dengan menggabungkan job queue, deduplikasi commit hash berbasis Redis atomic locks, dan multi-tier caching (PostgreSQL dan Redis).
Arsitektur Sistem Analitik Commit Terdistribusi
Pipeline analitik commit dirancang secara asinkron guna mengisolasi webhook ingestor dari latensi eksekusi LLM. Diagram alur operasionalnya adalah sebagai berikut:
- Ingestion: Git webhook mengirimkan commit payload ke ingestion service. Ingestion service hanya memvalidasi signature dan melempar array hash commit ke job queue (misalnya RabbitMQ atau Redis Stream).
- Deduplication Guard: Worker mengambil commit ID dan mengecek layer deduplikasi menggunakan Redis distributed lock sebelum parsing git diff.
- Cache Lookup: Worker memeriksa apakah ringkasan commit sudah tersimpan di database relasional atau Redis cache.
- Batching & Inference: Jika cache miss, commit diff digabungkan dalam micro-batch yang diatur token bucket limiter sebelum dikirim ke API LLM.
- Storage: Hasil ringkasan disimpan permanen ke database dan status kunci Redis diperbarui.
Deduplikasi Payload Menggunakan Redis Lock
Ketika developer melakukan rebase atau merge commit antar branch, hash SHA-1 atau SHA-256 yang identik dapat dikirim berkali-kali dalam hitungan detik. Mengirim payload ini berulang kali ke LLM membuang kuota API.
Deduplikasi diselesaikan pada level worker menggunakan Redis command SET key value NX EX. Perintah ini hanya menyetel key jika belum ada (Not eXists) dan memberikan waktu kedaluwarsa (TTL) secara atomik.
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
def acquire_commit_lock(commit_hash: str, lock_timeout: int = 60) -> bool:
lock_key = f"lock:commit:{commit_hash}"
# Nilai 1 disetel hanya jika key belum ada; TTL mencegah dead-lock jika worker crash
is_acquired = r.set(lock_key, "processing", nx=True, ex=lock_timeout)
return bool(is_acquired)
def release_commit_lock(commit_hash: str):
r.delete(f"lock:commit:{commit_hash}")
Jika acquire_commit_lock mengembalikan False, worker langsung menandai task tersebut sebagai duplicate dan mengabaikannya tanpa memproses diff atau memanggil LLM.
Multi-Tier Caching untuk Mencegah Token Exhaustion
Sebuah commit bersifat immutable; konten perubahan pada satu hash commit tidak akan pernah berubah. Maka dari itu, hasil ringkasan teks commit dapat di-cache secara permanen.
Layer 1: SQL Persistent Store
Tabel PostgreSQL bertindak sebagai source of truth. Skema memuat indeks unik pada commit hash untuk menjamin integritas data di level basis data:
CREATE TABLE commit_summaries (
id BIGSERIAL PRIMARY KEY,
commit_hash VARCHAR(64) UNIQUE NOT NULL,
repo_id VARCHAR(100) NOT NULL,
summary_text TEXT NOT NULL,
tokens_used INT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_commit_hash ON commit_summaries (commit_hash);Layer 2: Fast Read-Through Cache (Redis)
Sebelum melakukan query ke SQL atau menjalankan inferensi LLM yang mahal, worker membaca string cache dari Redis key summary:{commit_hash}. Alur validasi cache dilakukan bertingkat:
def get_or_generate_summary(commit_hash: str, diff_text: str) -> str:
cache_key = f"summary:{commit_hash}"
# 1. Cek Redis In-Memory
cached = r.get(cache_key)
if cached:
return cached.decode('utf-8')
# 2. Cek SQL DB
db_summary = query_summary_from_db(commit_hash)
if db_summary:
r.setex(cache_key, 86400, db_summary) # Simpan 24 jam di Redis
return db_summary
# 3. Cache Miss: Jalankan Inferensi LLM
summary = call_llm_inference(diff_text)
save_to_db(commit_hash, summary)
r.setex(cache_key, 86400, summary)
return summaryMitigasi Rate-Limit: Token Bucket & Micro-Batching
Penyedia API AI membatasi traffic berdasarkan Requests Per Minute (RPM) dan Tokens Per Minute (TPM). Memproses 500 commit push events secara individual memicu error HTTP 429 Too Many Requests.
Untuk mengatasinya, worker dirancang mengumpulkan diff dalam jendela waktu 2 detik (micro-batch) hingga mencapai batas maksimal token sebelum dikirim dalam 1 API call, dikontrol oleh algoritma Token Bucket.
class TokenBucketRateLimiter:
def __init__(self, capacity: int, fill_rate: float):
self.capacity = capacity
self.fill_rate = fill_rate
self.tokens = capacity
self.last_update = time.monotonic()
def consume(self, tokens_needed: int) -> bool:
now = time.monotonic()
elapsed = now - self.last_update
self.last_update = now
self.tokens = min(self.capacity, self.tokens + elapsed * self.fill_rate)
if self.tokens >= tokens_needed:
self.tokens -= tokens_needed
return True
return FalseJika token tidak mencukupi, job di-requeue atau ditunda menggunakan exponential backoff dengan jitter guna mencegah thundering herd problem pada endpoint penyedia LLM.
Debugging dan Edge Cases
- Worker Crash Saat Memegang Lock: Jika worker mati mendadak sebelum melepas lock, parameter
EXpada perintah Redis memastikan key terhapus otomatis setelah batas TTL berakhir, menghindari kondisi stale lock. - Truncation pada Commit Raksasa: Commit berupa merge besar atau regenerasi file lock dapat melebihi context window LLM. Terapkan pemotongan statis (misal: maksimum 4.000 token diff per commit) sebelum memicu inferensi LLM.
- Pencocokan Duplikat Lintas Branch: Pastikan deduplikasi memakai kombinasi
repo_id:commit_hashjika worker melayani repositori multi-tenant, guna mencegah tabrakan hash non-kriptografis antar repositori yang berbeda.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!