Bagaimana Elixir Membantu Anda Menulis Kode Serentak Bebas Bug

Informasi

Bagaimana Elixir Membantu Anda Menulis Kode Serentak Bebas Bug – Concurrency adalah istilah untuk sistem yang melakukan banyak operasi pada saat yang sama, dan praktis tidak dapat dihindari dalam pengembangan perangkat lunak modern. Misalnya, jika Anda membangun server apa pun yang menangani banyak klien, misalnya, Anda harus berurusan dengan konkurensi. Demikian juga di aplikasi seluler, dengan utas terpisah untuk antarmuka pengguna, panggilan jaringan, dll. Bahasa dan kerangka kerja yang berbeda menangani konkurensi secara berbeda, dan wajar untuk mengatakan bahwa beberapa menawarkan alat yang lebih baik daripada yang lain.

Bagaimana Elixir Membantu Anda Menulis Kode Serentak Bebas Bug

elixir-memory – Banyak bahasa mengekspos primitif seperti utas dan berbagai jenis kunci dan semacamnya serahkan kepada pengembang untuk mencari tahu sisanya. Dan sementara itu adalah alat inti yang Anda butuhkan untuk membuat aplikasi bersamaan, membuat kode bersamaan bebas bug itu sulit. Dalam posting ini, kita akan melihat bagaimana hal-hal yang salah dengan pemrograman bersamaan, dan bagaimana bahasa pemrograman Elixir, dengan bantuan Erlang/OTP (Open Telecom Platform), membantu kita menulis kode serentak bebas bug.

Konkurensi Apa Yang Bisa Salah (WCGW)?

Membangun aplikasi bersamaan berarti tidak lagi dapat bernalar melalui aliran linier ketat yang kita gunakan saat kita menulis kode ini menjadi sistem kompleks dari banyak hal yang berjalan secara independen dan berinteraksi satu sama lain. Ini dapat menyebabkan berbagai macam masalah. Studi kasus baru-baru ini tentang masalah konkurensi dalam perangkat lunak sumber terbuka menjelaskan kategori bug konkurensi potensial berikut ini:

  • Data race, ketika dua atau lebih utas mencoba mengakses dan menulis data yang sama.
  • Kebuntuan: ketika dua atau lebih utas mencoba mengakses sumber daya bersama yang dilindungi dengan kunci (biasanya dalam upaya untuk memperbaiki data race!)
  • Livelock: mirip dengan kebuntuan, kecuali satu utas sebenarnya tidak dikunci dan ini dijalankan terus menerus untuk mencoba mendapatkan sumber daya bersama.
  • Kelaparan: di mana suatu proses tidak dapat diselesaikan dalam waktu yang ditentukan karena sumber daya diberikan ke proses dengan prioritas lebih tinggi.
  • Penangguhan pemblokiran: ketika satu utas menunggu waktu yang sangat lama untuk sumber daya. Mirip dengan kelaparan, tetapi akhirnya berhasil.

Pelanggaran pesanan: ketika urutan operasi yang diinginkan antara banyak utas dilanggar.

Pelanggaran atomicity: di mana dua blok kode di utas disisipkan dengan blok kode di utas lain, sehingga hasil perhitungan tidak konsisten. Dengan kata lain, blok kode yang dimaksudkan atau diharapkan oleh pengembang atomik tidak dieksekusi secara atomik. Bug ini sangat sulit dikenali dalam kode dan alasannya. Banyak bug kode reguler dapat diatasi dengan langkah demi langkah melalui proses. Tidak demikian halnya dengan masalah konkurensi terkadang bug konkurensi hanya mewujudkan hal-hal yang benar-benar tidak terduga terjadi!

Misalnya, kode konkuren Anda mungkin bekerja dengan sempurna 99% dari waktu, tetapi memicu bug laten saat layanan eksternal tiba-tiba membutuhkan waktu terlalu lama untuk merespons. Selain itu, bug ini bisa jahat karena mungkin tidak terlihat jelas alih-alih membuat aplikasi Anda mogok secara terang-terangan, bug tersebut mungkin secara diam-diam merusak status program dan hanya menyebabkan masalah lebih lanjut, terpisah dalam ruang dan waktu dari masalah kode yang sebenarnya.

Baca Juga : Mempelajari Elixir Dan Membangun SaaS Dengan Phoenix Framework

Bagaimana Elixir Mencegah Bug Konkurensi

Jadi, sekarang kita telah melihat betapa menakutkan bekerja dengan konkurensi, kita akan mengeksplorasi bagaimana Elixir membantu Anda menghindari masalah ini. Perhatikan bahwa sementara Elixir membantu Anda menulis kode bersamaan bebas bug, itu tidak menjamin bahwa kode Anda akan melakukannya. Misalnya, sementara Elixir menghilangkan beberapa penyebab umum kebuntuan dengan kotak surat pola aktor, tentu saja mungkin untuk membuat kebuntuan dengan memiliki dua atau lebih proses yang menunggu satu sama lain untuk memproses pesan. Ini akan menunjukkan masalah arsitektur dalam kode Anda, dan mudah dihindari, tetapi intinya adalah Elixir tidak akan secara ajaib mencegah Anda melakukannya. Karena itu, mari lompat ke bagaimana Elixir dapat membantu Anda memperbaiki kode dan menghindari masalah konkurensi.

Pemrograman Fungsional Tidak Ada Status Bersama

Bekerja dengan status yang dapat diubah adalah salah satu sumber masalah terbesar dalam sistem konkuren. Anda mungkin berakhir dengan bug di mana dua proses mencoba mengubah struktur yang sama pada waktu yang sama; atau satu proses mencoba membaca struktur saat sedang diperbarui oleh proses lain. Bug ini biasanya diselesaikan dengan menggunakan beberapa bentuk penguncian, yang menimbulkan jebakannya sendiri, masalah kinerja atau kebuntuan adalah masalah umum yang muncul saat mencoba mengatasi masalah mutabilitas ini. Salah satu alasan utama Elixir dapat menghindari bug konkurensi adalah karena tidak ada keadaan yang dapat diubah sama sekali ini adalah bahasa pemrograman fungsional. Tentu saja, keadaan kadang-kadang diperlukan untuk membuat program melakukan hal-hal yang berguna, jadi Elixir mengaktifkan keadaan semacam itu, tetapi itu terisolasi dengan baik ke tingkat proses dan diimplementasikan saat fungsi proses dipanggil dengan nilai baru. Akibatnya, tidak ada status bersama yang dapat diubah untuk ditangani, dan kunci biasanya tidak diperlukan untuk pengelolaan status (walaupun, meskipun kurang umum, kunci masih dapat digunakan untuk hal lain, seperti sumber daya eksternal).

Model Aktor & Kotak Surat

Model aktor adalah pendekatan konkurensi yang melibatkan banyak proses yang disebut aktor yang bekerja secara independen dan berinteraksi melalui pesan. Saat pesan diterima, pesan tersebut dapat diproses oleh aktor secara linier. Karena pesan dikirim dalam antrian dan diproses secara linier, kami dapat menjamin bahwa kode yang dimaksud dijalankan secara atomik yaitu kami dapat memastikan bahwa pesan diproses satu per satu, dan secara keseluruhan. Pertimbangkan misalnya, potongan kode yang membaca, mengedit, dan menulis ke file di disk. Tanpa beberapa bentuk sinkronisasi, file dapat dengan cepat rusak karena dua utas mencoba menulis file pada saat yang bersamaan.

Sama seperti mengelola status bersama, bahasa lain mungkin menggunakan semacam mekanisme penguncian untuk mengatasi hal ini, tetapi dalam model aktor, tidak memerlukan penanganan khusus, jika satu proses bertanggung jawab atas tugas tersebut, ia akan memproses pesan secara berurutan. Manfaat lain yang menarik dari model aktor adalah bahwa jika kita merancang sistem kita untuk digunakan agar bekerja dengan benar dengan model aktor, kita tidak terlalu peduli di mana kode kita dieksekusi karena, kita dapat berinteraksi secara mulus dengan kode yang berjalan di server lain! Ini dapat membantu kami menskalakan aplikasi secara horizontal ke server lain saat diperlukan.

Proses Terisolasi Ringan

Melanjutkan tema model aktor, Elixir mendorong konkurensi melalui penggunaan proses terisolasi yang ringan. Banyak bahasa dan waktu proses menggunakan utas tingkat OS untuk konkurensi. Utas level OS, secara relatif, intensif sumber daya. Mereka memerlukan alokasi dan dealokasi memori, tingkat penggunaan memori berkelanjutan sepanjang masa pakainya, dan penggunaan CPU non-sepele yang didedikasikan untuk penjadwalan. Banyak sistem memiliki batasan keras dan batasan praktis pada jumlah utas yang dapat dibuat. Meskipun mungkin berbeda menurut platform dan bahasa, biasanya batas ini mencapai ratusan atau ribuan, tetapi secara praktis, banyak sistem dirancang untuk menggunakan jauh lebih sedikit (mungkin kurang dari 10).

Elixir dan Erlang/OTP di sisi lain, gunakan proses yang ringan sebagai gantinya (jangan bingung dengan proses tingkat OS itu sama sekali tidak ringan!). Proses Elixir menggunakan sangat sedikit sumber daya untuk membuat dan mengeksekusi, artinya kita dapat membuat puluhan ribu atau lebih untuk dijalankan secara bersamaan tanpa dampak besar pada kinerja, setidaknya untuk manajemen proses itu sendiri. Proses-proses ini dijalankan secara independen (mereka tidak berbagi status) dan sepenuhnya terisolasi, jika satu proses macet, itu tidak memengaruhi yang lain.

Mampu dengan mudah membuat begitu banyak proses mengubah cara kita merancang sebuah sistem: kita dapat memiliki proses khusus dan terisolasi untuk bagian sistem yang lebih kecil. Misalnya, kami dapat memiliki proses terpisah untuk masing-masing klien dalam game, aplikasi obrolan, atau jenis sistem interaktif real-time lainnya, dan dengan mudah menangani ratusan ribu di antaranya! Perhatikan bahwa Erlang VM sendiri menggunakan utas tingkat OS untuk menjalankan proses guna mengoptimalkan penggunaan CPU (biasanya jumlah inti CPU). Tetapi karena ini adalah utas yang tetap dan berjumlah kecil, ia tidak membawa banyak biaya tambahan dalam hal pembuatan atau pengelolaan utas.

Pohon Proses & Pengawas

Membangun di atas utas proses terisolasi ringan, salah satu aspek yang lebih menarik dari manajemen konkurensi dengan Elixir adalah filosofi penanganan kesalahan. Biarkan macet berarti bahwa karena perhitungan kami sangat terisolasi, kami dapat menangani jenis kesalahan tertentu hanya dengan membiarkan proses macet. Kerusakan proses sepenuhnya terisolasi dan tidak dapat melumpuhkan seluruh sistem kami, dan kami dapat memulihkannya dengan menginisialisasi ulang proses. Erlang/OTP menjabarkan proses ke dalam struktur pohon hierarkis yang disebut pohon pengawasan. Setiap node dalam pohon bertanggung jawab untuk mengelola anak-anaknya, termasuk memutuskan apa yang harus dilakukan jika proses macet. Meskipun ada banyak strategi pemulihan berbeda yang tersedia, yang paling mendasar adalah memulai kembali proses yang gagal.

Sebagai contoh, mari pertimbangkan untuk membuat klien obrolan waktu nyata seperti Slack. Kami memiliki banyak pengguna yang terhubung ke sistem melalui Websockets atau beberapa protokol serupa. Di Elixir, kami dapat merancang ini dengan proses soket khusus untuk setiap pengguna. Mungkin karena konektivitas jaringan yang buruk pada klien, soket kami kadang-kadang menutup tiba-tiba bagaimana kami menangani kesalahan yang mungkin terjadi pada sistem kami? Di Elixir, salah satu strategi yang valid adalah tidak melakukan apa-apa proses untuk pengguna akan macet tanpa memengaruhi sistem lainnya, dan koneksi dapat dibangun kembali sesuai kebutuhan dengan proses baru. Di sistem lain tanpa proses yang terisolasi ini dan filosofi biarkan macet, kami setidaknya memerlukan beberapa penanganan pengecualian dan pembersihan data, jika tidak, satu kegagalan klien dapat menghentikan seluruh utas atau proses, memengaruhi lebih banyak pengguna di sistem.

Rekap Dan Elixir Mengaktifkan Konkurensi Langsung Dari Kotaknya

Bagian terbaik tentang kisah konkurensi Elixir adalah bahwa semua ini adalah bagian dari Elixir langsung dari kotaknya. Sementara beberapa bahasa mendukung beberapa fitur ini melalui add-on dan perpustakaan pihak ketiga, Elixir membuat hal-hal ini langsung ke dalam bahasa dan runtime itu sendiri. Lebih baik lagi, semua hal yang disebutkan di sini tidak hanya membuat konkurensi menjadi lebih sederhana dengan Elixir, tetapi juga membuat konkurensi menjadi sangat berkinerja! Jadi, meskipun Anda dapat membangun sistem bersamaan yang berkinerja tinggi dan bebas bug dengan banyak bahasa, Anda akan merasa jauh lebih mudah melakukannya menggunakan Elixir. Jika Anda lelah berkelahi dengan kebuntuan atau masalah mutlti-threading lainnya, cobalah Elixir.

Leave a Reply