Esensi Erlang Bukanlah Proses Ringan dan Message Passing (2023)
(stevana.github.io)- Kunci yang membuat Erlang mampu membangun sistem terdistribusi yang andal bukanlah proses ringan itu sendiri, melainkan behaviours yang menggeneralisasi pola berulang dalam konkurensi dan penanganan kegagalan
- behaviours menyediakan titik implementasi seperti interface, tetapi juga menyembunyikan penanganan konkurensi di dalam komponen umum seperti
gen_server, sehingga kode aplikasi menjadi lebih mirip logika sekuensial - Disertasi Joe Armstrong membahas kasus penyusunan sistem besar seperti AXD301 hanya dari komponen kecil seperti
gen_server,gen_event,gen_fsm,supervisor,application, danrelease supervisorme-restart proses yang gagal dengan strategi sepertione_for_onedanone_for_all, dan filosofi “Let it crash!” memindahkan tanggung jawab pemulihan ke pohon supervisor- behaviours berbentuk state machine memudahkan pengujian simulasi dan verifikasi formal, sehingga developer dapat berfokus pada semantik masalah, bukan pada kompleksitas konkurensi dan simulator
Masalah yang Ingin Dipecahkan Erlang
- Erlang bermula sebagai alat untuk membangun sistem terdistribusi yang andal
- Awalnya Erlang adalah library Prolog untuk membangun sistem terdistribusi yang andal, lalu menjadi dialek Prolog, kemudian menjadi bahasa mandiri
- Erlang digunakan untuk memprogram sentral telepon Ericsson, dan pada era 80–90-an menangani trafik berskala ratusan juta orang dengan SLA yang ketat
- Pada 1998, Ericsson melarang penggunaan Erlang; tim pengembang berargumen bahwa jika Erlang akan dilarang, sebaiknya dirilis sebagai open source, dan Ericsson pun melakukannya
- Joe Armstrong adalah salah satu tokoh inti dalam desain dan implementasi Erlang; pada 2002 ia mulai menulis disertasi doktoralnya di SICS dan pada 2003 menyelesaikan Making reliable distributed systems in the presence of software errors
- Disertasi ini lebih berfokus pada ide-ide yang menopang Erlang dan pengalaman membangun sistem terdistribusi yang andal, bukan pada matematika atau teori
- Ide besar Erlang bukanlah proses ringan dan message passing, melainkan komponen umum yang di Erlang disebut behaviours
behaviours: Gabungan Interface dan Infrastruktur
- Erlang behaviours adalah kumpulan type signature yang dapat memiliki banyak implementasi, seperti interface di Java atau Go
- Jika programmer menyediakan implementasi untuk interface tersebut, fungsi umum yang ditulis untuk interface itu dapat digunakan
- Perbedaan utamanya adalah behaviours melampaui interface sederhana dan juga menyediakan kode infrastruktur
- Programmer aplikasi menulis semantik masalah, yaitu business logic
- Kode infrastruktur seperti konkurensi disediakan otomatis oleh behaviour
- behaviours memuat praktik terbaik yang ditulis oleh para ahli berpengalaman
- Jika seluruh sistem menggunakan ulang sekumpulan kecil behaviour, maka ketika implementasi behaviour membaik, sistem juga dapat membaik tanpa perubahan kode
- Penggunaan behaviour memaksakan struktur, sehingga pengujian dan verifikasi formal menjadi lebih mudah
gen_server: Konkurensi yang Tersembunyi di Balik Kode Sekuensial
- Contoh
gen_serveradalah penyimpanan key-value;storemenyimpan pasangan key-value, danlookupmencari nilai dari sebuah key - Callback inti
handle_callmemperbarui stateDictpada requeststore, dan pada requestlookupmencari key dari state - Jika implementasi ini diberikan ke
gen_server, ia akan menghasilkan server yang mampu menangani requeststoredanlookupyang masuk secara bersamaan - Hal pentingnya adalah
handle_callitu sendiri sepenuhnya sekuensial- Konkurensi disembunyikan di dalam komponen umum
gen_server - Kode aplikasi menjadi mirip bentuk yang menerima state dan input, lalu menghasilkan state baru dan output
- Konkurensi disembunyikan di dalam komponen umum
- Disertasi Joe Armstrong memperluas pendekatan ini ke
gen_server,gen_event,gen_fsm,supervisor,application, hinggarelease
Kasus AXD301 dan Skala behaviours
- Joe Armstrong menggunakan sentral telepon AXD301 milik Ericsson sebagai studi kasus
- Proyek AXD301 mencakup komponen berikut
- 122 instance
gen_server - 36 instance
gen_event - 10 instance
gen_fsm - 20 supervisor
- 6 application
- Seluruhnya dikemas sebagai satu release
- 122 instance
- AXD301 adalah sistem dengan lebih dari 1 juta baris kode Erlang
- Fakta bahwa sistem sebesar ini disusun dari sekumpulan kecil behaviour menjadi dasar penting bagi struktur Erlang
Peran behaviours Lain
gen_eventadalah event manager umum- Ia mendaftarkan event handler, lalu menjalankan handler saat event manager menerima pesan terkait
- Joe Armstrong memberi contoh penggunaan seperti error logging
- Contoh logger dapat mencatat dan melaporkan lima pesan error terbaru
gen_fsmadalah behaviour state machine yang kemudian berganti nama menjadigen_statem- Lebih cocok untuk implementasi protokol
- Protokol sering dispesifikasikan sebagai state machine
- Setiap
gen_serverdapat dianggap bisa diimplementasikan sebagaigen_statem, dan sebaliknya
applicationterdiri dari pohon supervisor dan elemen lain yang diperlukan untuk pengiriman aplikasireleasemengemas satu atau lebih application- Juga mencakup kode penanganan upgrade
- Jika upgrade gagal, sistem harus dapat rollback ke kondisi stabil sebelumnya
supervisor dan “Let it crash!”
supervisoradalah proses yang memastikan proses lain berjalan normal- Jika proses yang diawasi gagal, supervisor dapat me-restart-nya sesuai strategi yang telah ditentukan
- Strategi
{one_for_one, 5, 1000}dalam contoh berarti sebagai berikut- Jika salah satu dari
packet_assembler,kv, atausimple_loggergagal, hanya proses yang gagal itu yang di-restart - Jika perlu restart lebih dari 5 kali dalam 1000 detik, supervisor itu sendiri gagal
- Jika salah satu dari
permanent, 500, workerberarti proses tersebut adalah worker yang harus selalu hidup, dan saat supervisor mencoba me-restart-nya, proses diberi 500 ms untuk berhenti secara normal- Dalam strategi
one_for_all, jika satu proses gagal, semua child process di-restart - supervisor dapat mengawasi supervisor lain, dan tidak harus berjalan di komputer yang sama
- Struktur ini bekerja pada level thread/proses ringan, bukan pada level container Docker, sehingga sulit dianggap sebagai “sekadar Kubernetes”
- “Let it crash!” mengasumsikan bahwa proses yang gagal akan di-restart
- Program hanya mengekspresikan jalur normal
- Jika terjadi masalah di jalur normal, program tidak mencoba memulihkan sendiri, melainkan crash
- Program lain di bagian atas pohon supervisor mengambil alih penanganannya
- Bukti stabilitas jangka panjang AXD301 tidak dikumpulkan secara sistematis, tetapi disertasi Joe Armstrong menyebut adanya angka PowerPoint bahwa seorang pelanggan besar mengoperasikan sistem 11 node dengan keandalan 99.9999999%
- Tidak terdokumentasi bagaimana angka tersebut diperoleh
- Angka dalam laporan downtime lain juga disertai catatan bahwa cara perhitungannya tidak jelas
Jika behaviours Diimplementasikan di Bahasa Lain
- Proses ringan dan message passing saja tidak membuat Erlang cocok untuk sistem yang andal
- Penjelasan yang lebih jujur adalah struktur yang diberikan behaviours dan bagaimana struktur itu mengarah pada software yang andal
- Signature interface
gen_serverdapat dilihat dalam bentuk berikutInput -> State -> (State, Output)- Artinya menerima input dan state saat ini, lalu menghasilkan state baru dan output
- Cara mengubah signature sekuensial ini menjadi penanganan request konkuren dapat dipikirkan seperti berikut
- Server HTTP mengubah request menjadi
Inputlalu memasukkannya ke queue - Event loop mengambil input dari queue dan meneruskannya ke implementasi sekuensial
- Output dikembalikan sebagai response ke client
- Untuk mendukung beberapa
gen_server, tiap server dapat diberi nama dan request dapat menyertakan nama serta input sekaligus
- Server HTTP mengubah request menjadi
gen_eventdapat diimplementasikan dengan mengizinkan pendaftaran callback untuk tipe event tertentu dalam queuesupervisordapat disederhanakan sebagai pembungkus pemanggilan fungsigen_serverdengan exception handler, lalu memberi tahu supervisor jika exception terjadi- Jika supervisor tidak berjalan di komputer yang sama, ini menjadi lebih rumit
applicationdanreleasepenting karena konfigurasi, deployment, dan upgrade adalah masalah yang sulit, tetapi tidak dibahas secara mendalam
behaviours dan Testability
- Struktur Erlang behaviours mengarah pada pengujian simulasi dan verifikasi formal
- Minat belakangan ini tertuju pada pengujian simulasi sistem terdistribusi ala FoundationDB
- Pengujian simulasi menjalankan sistem dalam dunia tersimulasi, dengan simulasi yang sepenuhnya mengontrol waktu pengiriman pesan jaringan
- FoundationDB membuat dialek C++ dengan actor, atau bahasa pemrogramannya sendiri, untuk pengujian simulasi
- Pendekatan ini dianggap bisa berjalan cukup jauh hanya dengan tipe state machine berikut
Input -> State -> (State, [Output])[Output]adalah urutan output
- Simulator mengelola pesan dengan priority queue berdasarkan waktu kedatangan
- Mengambil satu pesan
- Memajukan clock ke waktu kedatangan pesan tersebut
- Meneruskan pesan ke state machine penerima
- Membuat waktu kedatangan baru untuk pesan output dan memasukkannya kembali ke queue
- Jika semuanya deterministik dan waktu kedatangan dibuat dari seed, berbagai interleaving dapat dieksplorasi dan kegagalan yang dapat direproduksi bisa diperoleh
- Cara ini lebih cepat daripada Jepsen karena pesan diproses di dalam memori dan clock dimajukan ke waktu kedatangan tanpa menunggu timeout
- Bentuk state machine seperti ini disebut “network normal form” dan mengarah pada dugaan bahwa semua program yang menerima dan mengirim lewat jaringan dapat direfaktor menjadi bentuk ini
- Fakta bahwa
gen_serverdangen_statempada dasarnya memiliki struktur tipe yang sama dapat dilihat sebagai sinyal bahwa struktur ini tidak arbitrer
Verifikasi Formal dan Struktur State Machine
- Joe Armstrong pernah mengatakan dalam sebuah talk bahwa implementasi distributed leader election yang benar itu sulit
- Jika ada simulator, masalah ini dapat sangat disederhanakan
- Seperti wind tunnel membantu pembuatan pesawat, kondisi ekstrem seperti jaringan tidak stabil atau kehilangan daya dapat diuji sebelum production
- Simulator ini dapat bersifat umum atau terparametrisasi terhadap behaviours
- Developer tidak perlu menulis simulator secara terpisah
- Kompleksitas disembunyikan di balik behaviour, seperti kode konkurensi
gen_server
- Terkait pengujian FoundationDB, Kyle “aphyr” Kingsbury menulis tweet yang intinya mengatakan bahwa pengujian FoundationDB tampak jauh lebih ketat daripada pengujian Jepsen miliknya
- Verifikasi formal juga menjadi lebih mudah jika program ditulis sebagai state machine
- Pekerjaan model checking TLA+ oleh Lamport mengasumsikan bahwa spesifikasi adalah state machine
- Kleppmann menunjukkan cara menangani masalah state explosion melalui induksi struktural yang memanfaatkan struktur state machine
- Struktur yang diperoleh dari Erlang behaviours dapat digunakan kembali untuk memecahkan masalah yang menurut Joe Armstrong sulit
Pekerjaan Terkait dan Referensi
- Pekerjaan terkait yang mengambil ide dari Erlang antara lain sebagai berikut
- Pekerjaan membuat event loop cepat tempat behaviours dijalankan, dengan mengambil ide dari LMAX Disruptor karya Martin Thompson dan aeron
- Pekerjaan menambahkan async I/O ke tipe state machine
- Pekerjaan mengimplementasikan supervisors secara lebih rinci
- Hot code swapping untuk state machine
- Referensi yang diberikan mencakup disertasi doktoral Joe Armstrong, OTP design principles, serta dokumentasi
gen_server,gen_event,gen_statem,supervisor,application, dan release - Mengenai hubungan antara actor model dan Erlang, dijelaskan bahwa para pengembang Erlang membuat Erlang tanpa mengetahui actor model, dan bahwa makalah Carl Hewitt mendokumentasikan perbedaan antara proses Erlang dan actor model
- Akka memiliki “actors” dan supervisor trees, tetapi tampaknya tidak memiliki padanan untuk behaviours Erlang lainnya; konsep “behavior” di Akka juga berbeda dari Erlang behaviours
1 komentar
Opini Hacker News
Hal yang menakjubkan dari Erlang dan BEAM adalah kedalaman fiturnya. Dalam tulisan aslinya, Behaviour/Interface adalah kesan utamanya, tetapi bagi saya yang lebih besar adalah bahwa saat membangun sistem kompleks, ini bisa dilakukan dengan resource pengembangan yang jauh lebih sedikit dibanding bahasa lain
OTP sendiri juga berisi banyak hal. Saya pernah mencoba mengompilasi Elixir agar berjalan di perangkat iOS, dan selain proses release Erlang, saya juga bisa memakai library ei untuk mengompilasi Node dalam C dan berkomunikasi dengan node Erlang lain seperti Erlang, Elixir, Gleam, dan sebagainya layaknya jaringan terdistribusi biasa
Selain itu, melalui library rpc Erlang, dari C pun saya bisa memanggil fungsi aplikasi Elixir. Memang ada overhead encoding/decoding dan FFI mungkin lebih cepat, tetapi itu masih cukup masuk dalam budget latensi, dan saya bisa menyiapkan fitur yang sebelumnya bahkan belum pernah saya dengar hanya dalam beberapa hari
Poin yang lebih besar adalah bahwa Erlang sudah menyelesaikan banyak masalah yang kini masih digeluti stack teknologi modern, puluhan tahun lalu, baik dari sisi skala maupun biaya implementasi. HN memang punya sisi yang menunjukkan kecintaan clickbait terhadap Erlang/Elixir, tetapi itu tidak berujung pada adopsi nyata, dan ada perusahaan-perusahaan yang membakar uang untuk mengimplementasikan hal-hal yang pada stack Erlang didapat gratis secara default
Proyek yang saya kerjakan adalah pipeline data backend, dan data yang diproses pun tidak banyak, tetapi mengisolasi bug inti secara tepat terasa luar biasa sulit
Dalam proses itu saya mempelajari berbagai karakteristik Node.js, dan setelah membandingkannya dengan Elixir/Erlang/OTP, saya sampai pada kesimpulan bahwa Node.js secara desain kurang andal
Saya juga banyak memakai Ruby dan pernah menyentuh Python, tetapi banyak platform bahasa generasi sekarang kesulitan membangun sistem terdistribusi yang andal. BEAM VM dan platform OTP sudah menyelesaikan bagian itu
Misalnya GenServer, yang berperan sebagai worker di sebagian besar sistem BEAM, pada akhirnya merupakan struktur yang memanggil beberapa fungsi dengan parameter sederhana
Jadi kita bisa mengujinya dengan memanggil fungsi-fungsi itu langsung, meneruskan parameter secara manual, lalu memverifikasi output saja. Tidak perlu menyiapkan sistem pengujian rumit untuk menangani kode asynchronous atau berhenti menunggu pekerjaan selesai dalam test
Ini bagian yang sering terlewat oleh junior, tetapi begitu disadari, rasanya cukup membebaskan
Saya pernah melihat beberapa orang, terutama manajer, yang ingin menulis buku berdasarkan pengalaman kami. Yang selalu membuat frustrasi adalah mereka melihat bagian yang berbeda sebagai kunci dari alasan pekerjaan kami berhasil. Hal yang saya rasa esensial sering mereka kecilkan menjadi sekadar nice-to-have
Di sini pun ada yang mengatakan bahwa proses ringan dan message passing bukan saus rahasianya, tetapi melewatkan fakta bahwa cara memandang Erlang sebagai communicating sequential processes (CSP) tidak bisa dipisahkan dari karakteristiknya. Namun pada saat yang sama, mereka berulang kali menyebut CSP sebagai bagian dari saus rahasia
Misalnya, programmer aplikasi menulis kode sekuensial dan concurrency disembunyikan di dalam behaviour, atau business logic bersifat sekuensial sehingga anggota tim baru mudah memulai, atau supervisor dan filosofi “let it crash” menciptakan sistem yang andal
Behaviour itu menarik, umum pada era 80-an, dan menyelesaikan masalah yang masih dicoba dipecahkan sebagian pihak pada era 2000-an, tetapi di Erlang ia sekaligus tujuan dan sarana. Itu adalah cara Erlang mengimplementasikan karakteristik-karakteristik lain tersebut, tetapi saya tidak tahu apakah harus begitu agar Erlang tetap terasa seperti Erlang
CSP adalah jalur yang, melalui occam dan bahasa-bahasa lain, menginspirasi channel Go. Perbedaan yang paling jelas adalah cara sinkronisasi pada channel tanpa buffer, dan ada juga perbedaan seperti pattern matching terhadap mailbox dalam model aktor
Perdebatan CSP vs model aktor cukup menarik karena sekilas tampak mirip, tetapi implikasi sebenarnya sangat berbeda
Menurut saya model aktor lebih masuk akal, tetapi bisa sangat berbeda bagi tiap orang
Saya masuk karena ingin tahu lebih banyak mengapa Ericsson berhenti menggunakan Erlang, dan mengapa Joe dipecat
Singkatnya, Ericsson beralih ke Java untuk proyek-proyek baru, dan karena itu Erlang tampaknya termarginalkan. Setelah itu Joe dan rekan-rekannya mendirikan Bluetail pada 1998, lalu diakuisisi oleh Nortel
Nortel adalah raksasa telekomunikasi yang pernah menyumbang sekitar sepertiga nilai Bursa Efek Toronto. Pada 2000 harga sahamnya sempat mencapai 125 dolar per saham, tetapi pada 2002 jatuh ke bawah 1 dolar. Itu bagian dari pecahnya gelembung dot-com, dan bersamaan dengan penurunan tajam belanja telekomunikasi, Nortel terpukul sangat keras
Pemecatan Joe tampaknya aman dipandang sebagai situasi “di kapal yang sedang tenggelam, departemennya lebih dulu terendam air”. Nortel memberhentikan 60.000 orang, yaitu lebih dari dua pertiga seluruh tenaga kerjanya. PHK itu bukan sinyal bahwa Joe tidak menjalankan perannya dengan baik, dan juga bukan menunjukkan inefisiensi unit bisnis; itu adalah langkah massal yang putus asa
“fired” mengandung penilaian yang kuat dan memberi nuansa bahwa seseorang diberhentikan karena kesalahan. Kalaupun benar begitu, penulis tulisan asli tidak mungkin tahu, dan juga bukan urusannya
Saya mulai melirik Erlang lagi karena proses ringan dan message passing, dan sampai sekarang behaviour masih terasa sekunder
Proyek ini bertujuan membawa flow-based programming (FBP) visual ke Erlang. FBP rasanya seperti dibuat untuk Erlang, jadi cukup mengejutkan bahwa saya tidak melihat implementasi yang sudah ada
Alat yang terutama saya pakai untuk FBP adalah Node-RED, jadi ide dasarnya adalah menempelkan frontend Node-RED ke backend Erlang dan menjadikan semua node sebagai proses. Frontend Node-RED cocok untuk memodelkan pengiriman pesan antar-node, sehingga memungkinkan pemetaan 1:1 yang sangat sederhana ke proses dan pesan Erlang
Saya sudah mengimplementasikan sebagian fungsi dasar, dan mulai membuat flow sebagai unit test untuk menambah fitur secara perlahan. Akan bagus jika 100% kompatibel dengan Node-RED yang backend-nya Node.js. Detailnya ada di repositori GitHub → https://github.com/gorenje/erlang-red
Secara keseluruhan Erlang ternyata sangat cocok untuk ini, sampai saya heran mengapa belum ada yang membuat hal serupa. Atau mungkin sudah ada?
[1] = https://jpaulm.github.io/fbp/index.html
Bagi saya, kekuatan Erlang/Elixir bukan terletak pada implementasi model aktor, matching yang berasal dari Prolog, immutability, atau behaviour itu sendiri, melainkan pada tekad Joe untuk menunjukkan bahwa kita bisa melakukan lebih banyak dengan lebih sedikit
Ini adalah sistem komputasi yang dirancang dengan baik dan teruji, dengan konsistensi yang jarang terlihat di bahasa lain, apalagi di dunia “web”. Tidak sempurna, tetapi cukup mengesankan
Sayangnya, di dunia software, menurut saya pengakuan dan adopsi terhadap hal-hal yang dimungkinkan oleh kesederhanaan masih sangat kurang. Kompleksitas membuat orang menjadi pakar, membuat manajer bisa membenarkan tim besar dan banyak rapat, serta membuat para pakar tetap menjadi pakar
Erlang dikembangkan pada masa ketika perusahaan berusaha mengimplementasikan solusi software dengan lebih sedikit orang dan kinerja yang terbatas. Setelah itu, selama puluhan tahun uang mengalir deras ke bidang ini, sehingga nilai bahwa “lebih sedikit berarti lebih banyak dengan cara yang baik untuk semua orang” menjadi tampak kurang menarik
Konsep paling menarik di Erlang/BEAM adalah bahwa pemulihan parsial sudah tertanam sejak awal
Ketika bertemu keadaan yang tidak terduga, alih-alih mematikan seluruh proses atau terus berjalan dengan risiko kerusakan, sistem kembali ke keadaan normal yang diketahui pada tingkat sedetail mungkin
Gagasan ini sudah lama diteliti dengan nama “microreboots” dan juga terkait dengan “crash-only software”, tetapi hanya Erlang/BEAM yang menjadikannya konsep kelas satu dalam sistem operasional
Erlang menyediakan model yang baik untuk menangani masalah seperti ini, tetapi bukan berarti kita boleh berhenti berpikir sama sekali. Jika masuk dengan asumsi biarkan saja restart dan semuanya akan baik-baik saja, Anda bisa kena batunya
Erlang, OTP, dan BEAM menawarkan lebih dari sekadar behaviour. VM-nya lebih mirip kernel virtual yang memiliki supervisor, proses terisolasi, dan mode terdistribusi yang memperlakukan beberapa mesin fisik/virtual sebagai satu pool resource
OTP juga menyediakan beberapa mode berguna seperti Mnesia sebagai database, counter atomik untuk caching, dan tabel ETS. Runtime-nya juga mendukung hot reloading bytecode sehingga patch bisa diterapkan tanpa menghentikan sistem. Sintaksnya tidak ramah screen reader, tetapi masih bisa dibaca
Platform yang terpikir sebagai sesuatu yang mirip dengan BEAM dalam kemampuan memperlakukan resource dari beberapa mesin sebagai satu pool kurang lebih hanya Apache Mesos[1]
Sekitar setahun lalu, perusahaan konsultasi pribadi saya mengadopsi Erlang sebagai bahasa backend. Sejak itu kami mulai menelusuri bagian dalam BEAM, misalnya mengganti stack berbasis TCP dengan QUIC atau mengintegrasikan patch Rust
Ini benar-benar pilihan yang sangat bagus untuk sistem ringan dan throughput tinggi yang tidak gagal kecuali terjadi kernel panic atau kehilangan daya. Saat ini kami membuat software yang sangat sibuk dan sangat konkuren seperti tracker produksi film/game dan pipeline manager, serta sedang menyiapkan R&D untuk layanan manajemen rumah sakit swasta
[1]: https://mesos.apache.org/
Besar kemungkinan kami harus memelihara sendiri binding internal atau implementasi untuk hal-hal di sisi Elixir yang tidak lagi dipelihara
Selain itu, ada banyak syntax sugar, dan para penggunanya menunjukkan obsesi yang agak aneh untuk mengabstraksikan sesuatu menjadi antarmuka DSL
Ada alasan di balik pertanyaan, “mengapa para perancang bahasa dan pustaka hanya meniru ide proses ringan dan pengiriman pesan, tetapi tidak mencuri struktur di balik behaviour Erlang?”
Signature fungsi pada behaviour Erlang sangat terkait dengan fitur-fitur Erlang lain, terutama cara penggunaan immutability-nya yang unik. Itulah juga alasan server memerlukan panggilan init terpisah, dan agar manajemen state bekerja dengan cara yang sama, bentuknya harus sangat jelas
Namun untuk mencapai tujuan yang sama di bahasa lain, hampir selalu ada banyak kasus di mana kita tidak boleh menyalin begitu saja apa yang dilakukan Erlang. Jika seseorang mengatakan “saya mem-port gen_server ke bahasa lain” lalu menampilkan antarmuka yang persis sama dengan Erlang, saya menganggap itu porting yang tidak memahami secara mendalam apa yang dilakukan Erlang
Ketika saya memindahkan ide supervisor tree ke Go[1] pun, saya melakukannya dengan cara yang idiomatis untuk Go. Di Go modern, antarmuka yang tepat untuk sesuatu yang “dapat diawasi” bukan signature seperti Erlang, melainkan hanya ini
type Service interface {
Serve(context.Context)
}
Di Go, hanya itu, dan sebaiknya cukup memakai sebanyak itu. Di bahasa lain bisa berbeda. Karena Go punya channel, tidak perlu “handle_event/2”, dan itulah yang harus dipakai. Bukan karena channel lebih baik atau lebih buruk, melainkan karena bahasa itu bekerja seperti itu
Di bahasa lain kita bisa memakai hal lain, dan di infrastruktur lain, alih-alih “memanggil handle_event/2”, kita juga bisa mengirimnya ke Kafka atau bus event cloud. Intinya adalah membuat sistem berbasis event, bukan menyalin implementasi persis Erlang
Di komunitas Erlang ada masalah berupa keyakinan berlebihan bahwa ada sesuatu yang luar biasa istimewa pada cara persis Erlang melakukannya, dan jika dilakukan berbeda maka itu langsung salah serta tidak bisa dipercaya. Mungkin itu benar pada 2005, tetapi tidak pada 2025
Dulu Erlang hampir menjadi satu-satunya jawaban yang masuk akal, tetapi masalah pada 2025 adalah menavigasi banjir jawaban. Saya sangat merekomendasikan belajar dari Erlang untuk perangkat lunak yang andal, tetapi sangat menentang mem-port secara membabi buta cara persis Erlang mencapai hal itu ke bahasa lain. Dalam hampir semua konteks bahasa lain, itu adalah jawaban yang salah. Bahkan bahasa immutable lain pun strukturnya cukup berbeda sehingga tidak bisa disalin begitu saja
[1]: https://jerf.org/iri/post/2930/
Sebagai orang yang memakai Elixir secara profesional, inilah pertanyaan paling menarik tentang Erlang bagi saya
Melihat keberhasilan besar k8s, Kafka, dan produk sistem terdistribusi AWS, jelas ada permintaan yang sangat besar terhadap alat yang membantu merancang sistem konkurensi yang andal. Namun mengapa Erlang/Elixir gagal mengambil pangsa itu?
Saya sering mendiskusikannya dengan teman-teman, tetapi tidak tahu jawabannya
Saya rasa Erlang telah mengabstraksikan penanganan pesan jaringan. Selain itu, saya sudah melihat 3–4 variasi pola yang diusulkan untuk hal-hal seperti server yang berjalan lama
Saya sepenuhnya setuju bahwa saat melakukan porting, kita harus memakai komponen yang idiomatis. Namun sebuah bahasa bisa memiliki mekanisme tersembunyi yang membuat esensi bernilai hilang dalam proses porting. Bisa dibilang ini semacam anti-relativisme bahasa pemrograman
“Channel? Tinggal bungkus dengan X saja” mungkin jauh lebih merugikan interoperabilitas daripada kedengarannya. Misalnya, lihat http.Handler di Go: sederhana, tetapi fakta bahwa ia ada di standard library punya implikasi praktis besar. Ekosistem middleware yang pada umumnya saling kompatibel bisa muncul tanpa koordinasi sebelumnya
io.Reader dan kawan-kawannya juga serupa. Antarmuka yang sangat sederhana seperti ini bisa dianggap lebih berharga daripada implementasinya
Ini spekulasi, tetapi jika Erlang berhasil menetapkan banyak antarmuka yang tepat untuk sistem terdistribusi yang andal, bisa jadi justru itulah faktor yang memungkinkan semuanya
Saya tidak setuju. Antarmuka adalah konsep sepele yang bisa ditempelkan ke bahasa apa pun. Bahkan pada bahasa tanpa sintaks antarmuka resmi, kita bisa menirunya di ruang program
Alasan BEAM berhasil adalah karena ia bisa menjalankan 1 juta proses pada satu node, mudah mengekspresikan state machine terdistribusi yang kompleks, dan bisa me-restart sebagian sistem tanpa downtime. Ada banyak alasan lain juga
Saya benar-benar tidak berpikir behaviour/interface adalah bagian yang paling inti
Heap proses yang terisolasi bisa memakai proses OS, supervisor tree bisa memakai Kubernetes, pengiriman pesan bisa dibuat di Java dengan dua thread dan shared queue, hot code loading juga bisa dilakukan Java, dan pemrosesan latensi rendah bisa saja mengalahkan Erlang jika LMAX Disruptor di-tuning, dan seterusnya
Namun intinya adalah mengumpulkan semua ini dalam satu platform atau pustaka. Proses OS itu berat, dan tidak mudah menjalankan 2 juta proses di server. Jika memakai green thread atau promise, kita kehilangan heap yang terisolasi
Kubernetes juga bisa dipakai sampai batas tertentu, tetapi tidak menangani supervisor tree bersarang dengan baik. Mungkin bisa dilakukan, tetapi selain kode akan muncul berbagai hal seperti pod, controller, volume, dan sebagainya
Kita bisa melakukan pengiriman pesan dengan pustaka actor di berbagai bahasa, tetapi itu tidak mengintegrasikan secara transparan pattern matching pada receive atau pengiriman ke thread lain di node lain
Hot code loading juga mungkin, tetapi masalahnya adalah bagaimana menangani struktur data runtime dan state. Erlang dibangun dengan hal itu sebagai pusatnya, dan karena state gen_server bersifat immutable dan eksplisit, ia memiliki callback untuk meng-upgrade bukan hanya kode, tetapi juga state itu sendiri
Saya tidak mengatakan BEAM menghilangkan masalah ini, tetapi tampaknya ia menurunkan kemiringan kurvanya. Idiom dan fitur yang konsisten secara internal, termasuk deployment, pemulihan otomatis, dan load balancing, mengurangi friksi antarmodul
Ia memungkinkan 12 engineer mengelola 30 endpoint dengan mudah, dan membuat sistem yang surface area-nya tetap bisa mengikuti power law
Saya tidak setuju dengan isi tulisan ini. Behaviour dimungkinkan karena arsitektur dasar sistem
Behaviour bukanlah antarmuka, melainkan lebih mirip objek abstrak dalam bahasa seperti Java. Ia mengimplementasikan fungsionalitas mendasar dan mandiri yang tersembunyi di balik antarmuka kolaborasi, tetapi tidak bisa berbuat banyak tanpa infrastruktur dasar yang menjamin bahwa setiap proses sepenuhnya terpisah dari proses lain, semua proses dapat ditutup dengan aman tanpa kebocoran memori atau sumber daya, dan pointer berbahaya tidak dapat dibagikan di antara dua proses
Yang ditunjukkan Joe dalam makalahnya adalah bagaimana membangun sistem yang andal, bahkan sampai taraf tertentu sistem terdistribusi yang andal, dengan sekumpulan blok Lego yang diberikan
Untuk mengimplementasikan hal seperti itu dengan benar, diperlukan Erlang VM, dan itu tidak dapat diimplementasikan sepenuhnya di VM lain. Tanpa perpipaan di lapisan bawah, supervision tree akan bocor. Di Java, Anda tidak bisa mematikan thread yang memegang sumber daya lalu berharap semuanya selalu berjalan baik, dan juga tidak ada cukup cara untuk memantau proses yang berbeda