Pendahuluan

Pipeline build modern sering terkendala oleh waktu linting, bundling, dan task lain yang berjalan secara serial. Shared-memory threads Bun memungkinkan memecah beban kerja tersebut ke dalam thread yang berbagi ruang memori di JavaScriptCore, tanpa harus mengorbankan keamanan data. Dalam artikel ini, kita langsung ke arah solusi: memanfaatkan thread Bun untuk mempercepat tooling developer dan CI/CD.

Dengan mengaktifkan shared-memory threads, linting cache dapat diakses oleh beberapa task sekaligus, bundler bisa membagi parsing dan transform, dan task paralel dapat memanfaatkan state bersama. Hasilnya adalah pipeline yang lebih responsive dan waktu rilis yang lebih singkat.

Apa itu Shared-Memory Threads di Bun

Bun menambahkan dukungan shared-memory threads ke JavaScriptCore, artinya worker dapat membaca dan menulis buffer yang sama tanpa kebutuhan serialization eksplisit. Ini cocok untuk tooling build, karena file cache, metadata, atau dependencies bisa direktori dalam buffer tunggal yang diakses beberapa task.

Konfigurasi dasar dilakukan via bunfig.toml. Sertakan aturan thread bersama:

[threads]
shared_cache = true
max_workers = 6

Dalam contoh di atas, shared_cache membuka jalan bagi thread linting/bundling mengakses cache tunggal. Thread-safe cache memastikan hanya operasi atomik yang merubah metadata, sementara operasi baca tetap cepat.

Menerapkan Cache Linting Thread-Safe

Salah satu bottleneck linting adalah pemindaian file yang sama berulang kali. Dengan shared-memory threads, kita bisa meletakkan cache linting di buffer bersama.

Contoh sederhana (di luar detail linting tertentu) seperti ini:

import { SharedArrayBuffer, Atomics } from 'bun:deno'

const cacheLock = new Int32Array(new SharedArrayBuffer(4))
const lintCache = new Map()

async function lintFile(path) {
  if (lintCache.has(path)) return lintCache.get(path)
  Atomics.add(cacheLock, 0, 1) // simple lock counter
  try {
    const result = await runLintOnPath(path)
    lintCache.set(path, result)
    return result
  } finally {
    Atomics.sub(cacheLock, 0, 1)
  }
}

Dalam konteks pipeline, multiple thread bisa memanggil lintFile secara bersamaan. Cache hanya diisi sekali per file, dan Atomics membantu menjaga konsistensi. Hindari deadlock dengan aturan jelas kapan lock diambil/dilepas.

Letakkan cache ini di worker yang dijalankan melalui Bun CLI:

bun run lint --threads --shared-cache

Flag seperti --threads membantu Bun memutuskan berapa banyak worker yang perlu diluncurkan. Pastikan lint cache memiliki batas ukuran untuk menghindari pertumbuhan memori tanpa batas.

Menjalankan Bundler dan Task Paralel

Bundler modern memerlukan beberapa langkah—pemindaian modul, transformasi, dan penulisan output. Shared-memory threads memungkinkan pipeline melakukan langkah awal (misal pemindaian dependensi) di satu thread, lalu meneruskan metadata ke thread lain tanpa serialization berlebihan.

Contoh arsitektur pipeline:

  1. Worker pertama membaca dan mem-parsing file, menyimpan hasil AST di buffer bersama.
  2. Worker kedua mengambil AST dari buffer untuk proses transformasi (misalnya transpile atau minify).
  3. Worker ketiga menulis output dan memperbarui hash cache di shared memory.

Setiap worker bisa dijalankan sebagai Bun worker yang diatur dalam skrip build.js:

import { Worker } from 'bun'

const sharedBuffer = new SharedArrayBuffer(1024 * 1024)
const syncView = new Int32Array(sharedBuffer)

const worker = new Worker('./bundle-worker.js', {
  type: 'module',
  deno: { sharedMemory: sharedBuffer }
})

worker.postMessage({ entry: './src/index.ts' })

Pada bundle-worker.js, gunakan Atomics.wait dan Atomics.notify untuk sinkronisasi. Hal ini mencegah polling berlebihan dan memastikan worker menunggu hingga data siap.

Dengan mengeksekusi task paralel di satu proses Bun yang sama, kita mengurangi overheat proses dan menghindari startup overhead yang biasanya terjadi saat memanggil CLI terpisah untuk setiap langkah.

Mengukur Dampak pada DX dan Waktu Rilis

Tidak cukup hanya mengimplementasikan shared-memory threads, kita perlu mengukur dampaknya terhadap developer experience (DX) dan waktu rilis.

Gunakan metrik berikut:

  • Waktu lint/bundling rata-rata di CI sebelum dan sesudah. Catat setiap stage agar bisa melihat langkah mana paling diuntungkan.
  • Pendekatan DX: apakah developers masih menunggu prompt init bundle? Apakah hot-reload lebih responsif karena cache lint dipakai ulang?
  • Throughput task paralel di pipeline: berapa banyak file yang diproses per detik jika shared memory aktif dibandingkan mode serial.

Untuk pengukuran, tambahkan logging waktu di tahap awal dan akhir skrip Bun:

const start = performance.now()
await runPipeline()
console.log('Pipeline selesai dalam', Math.round(performance.now() - start), 'ms')

Log ini bisa dikirim ke sistem observability CI untuk grafik per-bulan. Jangan lupa meninjau memory usage; shared-memory buffer membutuhkan manajemen agar tidak overcommit di CI runner dengan resource terbatas.

Kesimpulan: shared-memory threads Bun menawarkan jalur praktis untuk mempercepat linting, bundling, dan task paralel. Dengan desain cache thread-safe dan monitoring metrik yang konsisten, pipeline build bisa lebih cepat tanpa mengorbankan keandalan.