Sebagai seorang coder, terkadang kita membutuhkan mesin yang memiliki spesifikasi tangguh dan kecepatan internet yang cepat untuk menjalankanmake, yarn dev, ataupun npm install.

npm fucking install.

Jika beruntung, kantor akan memanjakan asset berharganya tersebut (baca: karyawan) dengan menawarkan mesin yang high-end serta berlangganan paket internet yang paling juara di kelasnya, demi menjaga kewarasan karyawannya di kantor.

Tapi mungkin itu di tahun 2018, di tahun 2020/2021, kondisi sedikit berubah.

Karyawan terpaksa untuk bekerja dari rumah demi kenyamanan dan keamanan bersama. Mesin yang tangguh terkadang terkalahkan oleh jaringan internet yang tidak bisa diandalkan. Terlebih, tidak semua mendapatkan fasilitas tersebut khususnya di mesin yang memiliki fisik bentuk fisik, beberapa ada yang dalam berbentuk virtual atau yang biasa disebut dengan Virtual Private Server (VPS).

Termasuk ditempat saya bekerja.

Saya tidak mempermasalahkan bentuk—baik itu fisik ataupun virtual—selagi saya memiliki akses ke sebuah program bernama terminal untuk menyelesaikan pekerjaan saya. Karena sejauh yang saya butuhkan hanyalah vim untuk menulis kode, dan peramban untuk melihat hasil dari kode tersebut karena saya adalah seorang Software Engineer yang mengkhususkan diri untuk mengurusi bagian depan dari sebuah peranti lunak berbentuk situs.

Menggunakan VPS yang memiliki spesifikasi tangguh pun relatif murah, asal jangan di AWS yang tagihan nya terbagi-terbagi dari elastic volume, elastic IP, dan elastic-elastic lainnya yang biasanya memiliki label scalable, anyway.

Saya saat ini tinggal di Bandung, sebuah kota yang masyarakatnya relatif ramah dan memiliki destinasi wisata yang cukup banyak untuk wisatawan dari Jakarta.

Saya menggunakan ISP Indihome untuk mengakses internet karena waktu itu ISP lain belum mendukung daerah tempat saya tinggal. Saya merasa beruntung menggunakan Indihome karena memiliki biaya yang murah, memiliki pelayanan pelanggan yang dapat diandalkan serta jaringan internet yang stabil dan cepat.

Hahaha oke oke, mari berhenti berbohong.

Saya memiliki hate-love relationship dengan Indihome, sebenci apapun saya dengan Indihome as company, nyatanya sampai hari ini saya masih menggunakannya.

Masalah

Aktivitas menulis kode saya berada di remote server, yang menggunakan sistem operasi Ubuntu untuk kantor dan FreeBSD untuk pribadi. Laptop saya sendiri adalah Macbook Air 2015 yang menggunakan sistem operasi Big Sur, alias, dari 3 mesin tersebut masing-masing menggunakan lingkungan dan keluarga yang lumayan berbeda.

Saya menggunakan remote server karena disana memiliki akses internet yang lumayan cepat yang mana bisa menyentuh 66.66 Mbps.

devbox pribadi menggunakan Linode

Selain itu, saya tidak ingin lagi menyiksa mesin kentang saya dengan proses-proses dari npm run build, npm run dev, dan terkadang docker build ... yang bisa memakan waktu bermenit-menit untuk skala di tempat saya bekerja.

Dan terlebih aktivitas tersebut memakan energi yang tidak sedikit juga yang berdampak terhadap kesehatan baterai khususnya baterai saya yang sudah dalam tahap "service recommended" ditambah harus menjalankan program lain, Google Chrome misalnya yang sudah menjadi rahasia umum bagaimana ia memakan sumber daya yang ada.

Selain itu, saya menggunakan 3 keluarga sistem operasi yang berbeda: GNU/Linux Ubuntu, FreeBSD 12, dan Mac OS 11. Yang menjadi PRadalah tentang bagaimana saya bisa bekerja secara optimal tanpa harus mengorbankan efektivitas apalagi sampai mengubah alur saya bekerja.

Percobaan pertama: VSCDR

Sebelumnya saya menggunakan "native support" remote development dari VSCode menggunakan plugin Visual Studio Code Remote Development kalau gak salah ingat, yang intinya saya menggunakan VSCode di local, namun kode dan terminal berada di remote.

Masalah disini ada 2: Pertama, menjalankan VSCode di local yang memakan sumber daya yang tidak sedikit. Kedua, koneksi dibuat diatas SSH yang sederhananya kurang-ramah-jaringan-Indihome alias kalau VSCRD kagak bisa melanjutkan sesi yang ada, maka VSCode harus dijalankan kembali alias proses yang ada harus dijalankan kembali dan semoga berkas yang sedang disunting tersimpan.

Karena SSH menggunakan protokol TCP dan kelemahan (let's call it feature) dari protokol tersebut salah duanya adalah harus melakukan handsake (SYN-SYN+ACK-ACK) dan tidak mentoleransi paket yang loss.

Percobaan kedua: code-server

Untuk mengatasi masalah diatas, gue coba mengakalinya dengan membuat paket yang dikirim/diterima menggunakan protokol UDP. Pertama, gue tidak menggunakan VSCDR lagi melainkan code-server sebagaimana yang pernah gue tulis disini.

Menggunakan code-server lumayan memuaskan, baik untuk diri sendiri ataupun laptop gue. code-server membuat VSCode berjalan di remote server, yang mana baik untuk laptop gue. Gue mengakses code-server melalui Tailscale/Wireguard yang mana menggunakan protokol UDP yang membuat koneksi lumayan stabil terkendali tanpa harus khawatir kehilangan sesi yang terjadi.

Oh iya, mungkin di benak anda kepikirkan "kenapa lu gak pake tmux sih" yang mana tentu saja gue pakai tmux. Namun poinnya bukan disitu.

Menggunakan code-server yang diakses melalui jaringan Wireguard lumayan menjaga kewarasan gue. Masalah utama yang gue rasakan adalah ketika code-server mencoba menyambungkan kembali ketika koneksi terputus entah karena alasan apa, gue tinggal menunggu sekalipus 1000 tahun lamanya tanpa perlu khawatir kehilangan sesi yang ada.

Sayangnya, kesabaran manusia memiliki threshold. Fitnah dajjal kalau sabar tidak ada batasnya apalagi kalau pakai Indihome.

Ketika sudah menyerah, gue hanya bisa pasrah "reload window" dan menunggu keajaiban apakah muncul "reconnect" lagi atau bisa kembali digunakan.

Kondisi diatas dapat dimengerti, karena:

  • code-server adalah sebuah aplikasi web, dan berukuran tidak kecil
  • code-server sekalipun didalam jaringan yang menggunakan protokol UDP, namun tetap diakses menggunakan protokol TCP (web)
  • Komunikasi melibatkan 3 pihak: klien <—> tailscale <—> server, yang sepertinya terdapat overhead yang menyebabkan latensi

Serta, gue curiga kalau AWS/EC2 ada ngebatasin egress bandwidth/outbound data transfer untuk lalu lintas yang kurang normal. Di beberapa kondisi, kadang gue kehilangan akses sama sekali ke mesin dan bos gue menjadi saksi karena sering gue mintain tolong buat reboot mesin.

Percobaan ketiga: kembali ke fitrah

And will never look back, ever.

Dan dengan setup yang lebih baik.

Pertama, gue say goodbye ke Tailscale. Terima kasih telah membantu saya untuk tidak perlu repot-repot bilang bos gue tiap mau buka/tutup port. Sekarang komunikasi hanya antara eth0 ec2 dan en0 laptop gue, dan cukup sekali mintol buka port untuk rentan 60k-61k/udp.

Kedua, tmux is first-class—now. Semua proses/aktivitas berada diatas tmux, apapun yang terjadi. Kalau sebelumnya tmux hanya digunakan untuk aktivitas terkait di "command line" seperti ls; ls; pwd; cd; biar terlihat seperti hacker.

Terakhir, gue pakai mosh daripada SSH. Mosh bukanlah solusi dari segala masalah, dan bukan sebagai pengganti SSH karena mosh sendiri bergantung dengan SSH karena mosh pada dasarnya berada diatas SSH. Namun setidaknya mosh membuat koneksi SSH menjadi lebih baik dan handal dalam menjaga kewarasan.

Solusi sementara

Apa yang terjadi ketika hubungan sudah tidak dapat dilanjutkan?

Putus dan move on. Fucking move on.

Begitupula dengan SSH, ketika hubungan sudah tidak dapat dilanjutkan, SSH akan memutuskan sambungan dengan alasan "client_loop: send disconnect: Broken pipe" yang hanya menyisakan kenangan untuk semua aktivitas yang sudah dilewati bersama.

Sorry sorry kebawa suasana.

Oke oke lanjut, dan tidak ada lagi yang bisa dilakukan selain move on dengan membuat sesi baru, meskipun masih dengan mesin dan jaringan yang sama, namun rasanya pasti berbeda, tidak seperti dulu.

Anjiiingggg.

Anyway, kembali ke mosh, mosh dapat membuat hubungan tersebut menjadi lebih dapat diandalkan sekalipun bertepuk sebelah tangan karena semesta jaringan internet tidak mendukung.

Mosh adalah tipe pasangan yang akan terus berjuang untuk mempertahankan hubungan, bagaimanapun kondisinya. Ketika membuat hubungan antara remote server dengan local melalui mosh, sederhananya, mosh akan membuat koneksi via SSH ke remote server untuk menjalankan mosh-server, menyalin koneksi SSH, lalu koneksi terjadi melalui mosh itu sendiri.

Mosh mengetahui kapan client tidak berkomunikasi dengan server (atau sebaliknya) yang singkatnya seperti melakukan "healthcheck" dan ketika itu terjadi, mosh akan menunggu sampai mosh-server dapat berkomunikasi dengan mosh-client.

contoh ketika buka vim lalu koneksi terputus

Dan ketika sudah dapat menyambung kembali, maka akan tersambung kembali dan sesi tidak hilang, kecuali kita sudah tidak ingin memperjuangkannya karena memang tidak dapat diperjuangkan, dan apalagi yang bisa dilakukan jika bukan putus.

Mosh tidak memiliki daemon, berukuran kecil, dan masa hidupnya hanya ketika koneksi tersebut benar-benar berakhir. Sekarang hampir workflow gue berada di iPad, yang seringnya menggunakan jaringan LTE. Ketika berpindah dari Wi-Fi ke LTE yang berarti ganti alamat IP, sesi yang ada masih tetap dapat dilanjutkan selagi tersambung ke jaringan internet.

Selain itu, mosh memiliki pendekatan untuk membuat pengalaman pengguna lebih baik, yang salah satunya adalah local echo. Ketika sedang berada di jaringan yang kurang stabil, dari sisi pengalaman pengguna, mosh terasa lebih baik karena apa yang kita ketik memiliki latensi yang lebih kecil daripada tanpa mosh (hanya SSH) karena SSH harus menunggu "jawaban" dari server untuk menampilkan apa yang kamu ketik, beda dengan mosh yang menggunakan "algoritma predicitve" untuk membuat respons terasa instan sekalipun di jaringan wifi.id gratisan.

Drawbacks

Hidup selalu tentang pengorbanan, ada beberapa kekurangan dari mosh yang bisa menjadi pertimbangan.

Pertama, mosh stable (3.12) tidak mendukung true colors (16m colors), dan ini menjadi masalah untuk para penggemar 256 color yang sangat memanjakan mata nya dengan warna. Solusinya ada 2: install mosh dari sumber (dan menggunakan versi edge, commit terakhir dari master/main) atau gunakan skema warna 16 colors (4 bits) daripada 256 colors (8 bits) ataupun 16m colors (24 bits).

Kedua, mosh tidak bisa melakukan "port forwading" alias melakukan tunneling karena memang bukan tanggung jawabnya. Biasanya kita membutuhkan ini untuk meneruskan koneksi dari port 3000 di server misalnya ke port 3000 di lokal.

Solusinya ada 2 juga: Gunakan ssh mode -f -N -M -s /path/socket.sock yang mana:

  • -f untuk fork koneksi SSH ke background
  • -N tidak perlu menjalankan perintah di remote server
  • -M untuk menjalankan dalam mode "master"
  • -s /path/socket.sock untuk membuat socket terkait koneksi SSH yang berjalan di background tersebut

Jadi untuk menyelesaikannya, tinggal ssh -S /path/socket.sock -O exit untuk mengirim "sinyal exit" ke SSH tanpa harus mengetahui pid dari proses tersebut.

Solusi kedua adalah dengan menggunakan et yang akan kita bahas dibawah :))

Terakhir, tidak ada dukungan "native scrollback" karena mosh "menggambar" tampilan berdasarkan "state" yang tampil di server ke lokal. Meskipun ini bisa sedikit diakali dengan menggunakan "scrollback" dari sesi tmux yang berjalan.

Alternatif: Eternal Terminal

Eternal Terminal atau et bisa menjadi alternatif bila kamu merasa "port forwarding" sangat krusial dan akan menjadi bencana bila tunneling tersebut ter-interupsi.

Sederhananya ET bekerja hampir mirip seperti mosh (komunikasi antara et-client dan et-server), namun menggunakan protokol TCP. Inti dari ET (sepemahaman gue) pada dasarnya untuk memastikan bahwa tidak ada paket yang loss ketika proses (TCP) reconnect, karena sekali lagi, protokol TCP tidak mentoleransi paket yang loss.

Selain itu, ET mendukung scrollback karena tidak seperti mosh yang hanya mengirimkan apa yang ada di "tampilan" server ke lokal yang singkatnya ketika kamu melakukan scrolling di local, yang kamu scroll itu adalah tampilan dari layar yang ada di terminal kamu, bukan server.

Terlihat sempurna? Tentu saja ET juga memiliki kekurangan.

Pertama, popularitas. Ini berpengaruh ke ekosistem. Contohnya, gue di iPad menggunakan Termius yang mana hanya mendukung SSH dan Mosh. Dan sayangnya di ISH tidak bisa menjalankan et.

Kedua, tidak ada instant echo. Beda dengan mosh yang menggunakan "algoritma" untuk membuat respon terasa instan seperti ketika mengetik, menavigasi, ataupun menghapus karakter menggunakan backspace. Masalah utama yang ingin diselesaikan oleh ET adalah membuat koneksi SSH tidak dapat terinterupsi dengan menjamin paket yang dikirim/diterima tidak ada yang loss, that's it.

Ketiga, karena apa yang ingin diselesaikan oleh ET tersebut, ET lebih cocok untuk yang memiliki masalah "tidak ingin sesi SSH berakhir karena jaringan" bukan seperti mosh yang "agar bisa berjuang dengan koneksi yang tidak stabil seperti bila menggunakan indihome sehingga gue kagak frustasi".

Personally gue menggunakan masih tetap menggunakan mosh karena masalah yang sedang gue alami adalah itu: Berjuang dalam jaringan yang tidak stabil.

Gue tidak ada masalah klo tunneling/port forward gue terputus karena apa yang menjadi fitur SSH itu sendiri, gue rasa melakukan tunneling lagi tidak sefrustasi lagi ngetik tiba-tiba hang lalu terputus. Gak, itu beda rasanya dengan ditinggal pergi pas lagi sayang-sayangnya.

Kenapa gak cuma tmux aja?

Karena tmux menyelesaikan masalah lain dalam konteks disini: Ia tetap menjaga proses di remote server berjalan sebagaimana seharusnya proses berjalan.

Maksudnya, ketika membuat sesi vim di dalam tmux, sekalipun koneksi/sesi ssh; mosh ataupun et terputus, kita bisa kembali ke sesi tersebut tanpa perlu khawatir sesi tersebut hilang.

Kasus gampangnya, lu lagi yarn test, terus koneksi terputus karena hal random yang sering terjadi pada pengguna indihome, semoga gue aja. Ternyata terputusnya lama, misal karena kabel fiber putus gegara mamang-mamang salah motong kabel pas lagi benerin kanopi sebagaimana kejadian yang gue alami kemaren.

Kalau gak pakai tmux, lu ga tau apakah yarn test tersebut berhasil apa kagak dan itu proses kagak bisa dilanjutin alias harus dimulai dari awal karena sesi lu terputus, kan? Oke mungkin proses nya masih berjalan, masih punya pid. Tapi gimana cara balik lagi ke proses itu?

Kalau pakai ssh+tmux, lu tinggal ssh lagi, attach, lalu proses yarn test tadi tetap berjalan, dan lu bisa balik lagi ke proses tersebut.

Kalau pakai mosh/et+tmux, karena ketika lo tutup laptop/gotong komputer dan jalan ke coffee shop favorit lo, terus buka laptop lalu konek lagi ke jaringan, apa yang lo liat dilayar 20 menit yang lalu akan kembali normal seperti tidak ada interupsi tanpa perlu melakukan ssh lagi.

Yang sederhananya: just use both. Karena itu baik untuk menjaga mood lo.

Penutup

Tulisan panjang ini sebenarnya hanya memiliki 3 poin untuk dapat tetap waras sekalipun di rumah menggunakan ISP indihome yang kagak stabil:

  • Gunakan tmux & vim
  • Gunakan mosh/et
  • Ngoding di coffee shop yang Wi-Fi nya tidak pakai indihome, ehm serta tetap pakai masker dan jaga jarak tanpa melupakan protokol kesehatan

Bercerita panjang lebar diatas untuk berbagi kefrustasian gue berikut dengan latar belakang motivasinya terkait mengapa menggunakan/melakukan 3 poin diatas.

Di masa pandemi ini kita semua sedang berjuang, dan peperangan kita tidak mudah karena memiliki 2 lawan: virus dan jaringan indihome yang kagak stabil.

WFH bukanlah penghalang untuk tetap bisa menyelesaikan pekerjaan melalui remote server di jaringan LTE sekalipun dan gue mencoba untuk berbagi pintu yang gue gunakan.

Jika kamu bekerja di indihome, cashtag Jenius gue adalah $faultable. Thanks.