Tantangan Webhook pada Pipeline Transpilasi Asinkron
Translasi source-to-source (seperti pipeline CTRAN) memakan waktu eksekusi yang bervariasi bergantung pada ukuran Abstract Syntax Tree (AST), optimasi compiler, dan resolusi dependensi. Komunikasi asinkron via webhook membebaskan klien dari koneksi HTTP blocking jangka panjang. Namun, arsitektur event-driven rentan terhadap serangan tampering, network drop, duplikasi event, dan delivery out-of-order.
Untuk menjaga konsistensi state proses build di sisi consumer, kontrak webhook membutuhkan skema payload terstandarisasi, mekanisme verifikasi integritas data berbasis cryptographic hash, serta penanganan konkurensi berbasis state.
Skema Kontrak Payload Event
Payload webhook harus membedakan dengan jelas status keberhasilan dan kegagalan kompilasi tanpa memerlukan round-trip request tambahan ke server.
{
"event_id": "evt_01J8F9X4B32A9M",
"event_type": "transpilation.completed",
"timestamp": 1711929600,
"job_id": "job_c_to_rust_8912",
"sequence": 3,
"data": {
"source_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"target_language": "rust",
"artifact_url": "https://storage.internal/artifacts/job_8912.tar.gz",
"diagnostics": {
"warnings": 0,
"errors": 0
}
}
}Jika terjadi kegagalan (misalnya parse error atau semantic error), event_type berubah menjadi transpilation.failed dengan field data.error terstruktur yang mencakup file path, baris, dan kode error compiler.
Verifikasi Integritas Data via HMAC Signature
Pengirim wajib menandatangani raw body request menggunakan SHA-256 HMAC dan shared secret. Sertakan timestamp di header untuk memitigasi replay attack. Receiver menolak request jika timestamp berselisih lebih dari 5 menit dari clock server lokal.
// Contoh validasi signature di Node.js receiver
import crypto from 'node:crypto';
function verifyWebhookSignature(rawBody, signatureHeader, timestampHeader, secret) {
const now = Math.floor(Date.now() / 1000);
const reqTime = parseInt(timestampHeader, 10);
if (Math.abs(now - reqTime) > 300) {
return false; // Replay attack window expired
}
const payloadToSign = `${reqTime}.${rawBody}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payloadToSign)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expectedSignature)
);
}Gunakan crypto.timingSafeEqual untuk mencegah timing side-channel attack selama proses pencocokan hash.
Mitigasi Race Condition dan Callback Out-of-Order
Distribusi webhook yang melibatkan worker paralel sering kali menyebabkan event status completed tiba lebih cepat daripada event started. Menyimpan nomor urut monotonic (sequence) pada database consumer mencegah penulisan state mundur.
-- Update atomic berbasis monotonic sequence
UPDATE transpilation_jobs
SET
status = $1,
artifact_url = $2,
last_sequence = $3,
updated_at = NOW()
WHERE id = $4 AND last_sequence < $3;Jika row count dari eksekusi SQL bernilai 0 sementara record ditemukan, event yang masuk diabaikan karena teridentifikasi sebagai event stale.
Idempotensi Receiver dan Pola Retry
Jaringan HTTP tidak menjamin zero-duplication. Receiver wajib memvalidasi event_id menggunakan database relasional unik atau Redis lock sebelum menjalankan side-effect.
Eksekusi Idempoten
- Ambil atomic lock menggunakan key
idempotency:event:{event_id}dengan TTL singkat (misal: 60 detik). - Cek apakah
event_idsudah tercatat di tabel riwayat pemrosesan webhook. Jika sudah, kembalikan HTTP 200 OK langsung tanpa memproses ulang artefak. - Tulis payload baru, update state job, dan rilis lock.
Exponential Backoff with Full Jitter
Ketika endpoint receiver mengalami kegagalan (HTTP 5xx atau timeout), dispatcher webhook harus menunda pengiriman ulang secara bertahap. Tambahan jitter mencegah thundering herd problem ke receiver.
function calculateRetryDelay(attempt, baseDelayMs = 1000, maxDelayMs = 32000) {
const exponentialLimit = Math.min(maxDelayMs, baseDelayMs * (2 ** attempt));
// Full jitter: nilai random antara 0 hingga limit eksponensial
return Math.floor(Math.random() * exponentialLimit);
}Implementasi backoff ini menjaga ketersediaan resource komputasi di kedua belah pihak selama pipeline transpilasi berjalan dalam volume tinggi.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!