Bot Telegram untuk pilihan artikel yang dipersonalisasi dari Habr

Untuk pertanyaan seperti “mengapa?” ada artikel lama - Natural Geektimes - membuat ruangan lebih bersih.

Artikelnya banyak sekali, karena alasan subjektif ada yang tidak saya suka, ada pula yang malah sayang untuk dilewatkan. Saya ingin mengoptimalkan proses ini dan menghemat waktu.

Artikel di atas menyarankan pendekatan skrip dalam browser, tetapi saya tidak terlalu menyukainya (walaupun saya pernah menggunakannya sebelumnya) karena alasan berikut:

  • Untuk browser berbeda di komputer/ponsel Anda, Anda harus mengkonfigurasinya lagi, jika memungkinkan.
  • Pemfilteran ketat oleh penulis tidak selalu mudah.
  • Masalah dengan penulis yang artikelnya sayang untuk dilewatkan, meskipun diterbitkan setahun sekali, belum terselesaikan.

Pemfilteran yang dibangun ke dalam situs berdasarkan peringkat artikel tidak selalu mudah, karena artikel yang sangat terspesialisasi, terlepas dari nilainya, dapat menerima peringkat yang agak sederhana.

Awalnya, saya ingin membuat RSS feed (atau bahkan beberapa), hanya menyisakan hal-hal menarik di sana. Namun pada akhirnya, ternyata membaca RSS terasa kurang nyaman: bagaimanapun juga, untuk mengomentari/memilih artikel/menambahkannya ke favorit, Anda harus melalui browser. Itu sebabnya saya menulis bot telegram yang mengirimkan artikel menarik kepada saya melalui pesan pribadi. Telegram sendiri membuat pratinjau yang indah, yang dikombinasikan dengan informasi tentang penulis/peringkat/pandangan, terlihat cukup informatif.

Bot Telegram untuk pilihan artikel yang dipersonalisasi dari Habr

Di bawah potongan terdapat detail seperti fitur pekerjaan, proses penulisan, dan solusi teknis.

Secara singkat tentang bot

Gudang: https://github.com/Kright/habrahabr_reader

Bot di telegram: https://t.me/HabraFilterBot

Pengguna menetapkan peringkat tambahan untuk tag dan penulis. Setelah itu, filter diterapkan pada artikel - peringkat artikel di Habré, peringkat pengguna penulis, dan rata-rata peringkat pengguna berdasarkan tag dijumlahkan. Jika jumlahnya lebih besar dari ambang batas yang ditentukan pengguna, maka artikel tersebut lolos filter.

Tujuan sampingan menulis bot adalah untuk mendapatkan kesenangan dan pengalaman. Selain itu, saya secara teratur mengingatkan diri saya akan hal itu Saya bukan Google, dan oleh karena itu banyak hal dilakukan sesederhana dan bahkan seprimitif mungkin. Namun, hal ini tidak menghalangi proses penulisan bot tersebut memakan waktu tiga bulan.

Saat itu musim panas di luar

Juli telah berakhir, dan saya memutuskan untuk menulis bot. Dan tidak sendirian, tapi bersama seorang teman yang menguasai scala dan ingin menulis sesuatu tentangnya. Permulaannya tampak menjanjikan - kodenya akan dipotong oleh sebuah tim, tugasnya tampak mudah dan saya pikir dalam beberapa minggu atau sebulan bot akan siap.

Terlepas dari kenyataan bahwa saya sendiri telah menulis kode di atas batu dari waktu ke waktu selama beberapa tahun terakhir, biasanya tidak ada yang melihat atau melihat kode ini: proyek kesayangan, menguji beberapa ide, memproses data terlebih dahulu, menguasai beberapa konsep dari FP. Saya sangat tertarik dengan seperti apa penulisan kode dalam sebuah tim, karena kode di atas batu dapat ditulis dengan cara yang sangat berbeda.

Apa yang mungkin terjadi jadi? Namun, jangan terburu-buru.
Segala sesuatu yang terjadi dapat dilacak menggunakan riwayat penerapan.

Seorang kenalan membuat repositori pada tanggal 27 Juli, tetapi tidak melakukan apa pun, jadi saya mulai menulis kode.

30 Juli

Secara singkat: Saya menulis parsing rss feed Habr.

  • com.github.pureconfig untuk membaca konfigurasi typesafe langsung ke kelas kasus (ternyata sangat nyaman)
  • scala-xml untuk membaca xml: karena awalnya saya ingin menulis implementasi saya sendiri untuk rss feed, dan rss feed dalam format xml, saya menggunakan perpustakaan ini untuk parsing. Sebenarnya RSS parsing juga muncul.
  • scalatest untuk tes. Bahkan untuk proyek kecil, menulis tes menghemat waktu - misalnya, saat men-debug parsing xml, jauh lebih mudah untuk mendownloadnya ke file, menulis tes, dan memperbaiki kesalahan. Ketika bug kemudian muncul dengan penguraian beberapa html aneh dengan karakter utf-8 yang tidak valid, ternyata lebih mudah untuk memasukkannya ke dalam file dan menambahkan tes.
  • aktor dari Akka. Secara obyektif, mereka tidak diperlukan sama sekali, tetapi proyek ini ditulis untuk bersenang-senang, saya ingin mencobanya. Hasilnya, saya siap mengatakan bahwa saya menyukainya. Ide OOP bisa dilihat dari sisi lain - ada aktor yang bertukar pesan. Yang lebih menarik adalah Anda dapat (dan harus) menulis kode sedemikian rupa sehingga pesan tidak sampai atau tidak diproses (secara umum, ketika akun berjalan di satu komputer, pesan tidak boleh hilang). Awalnya saya menggaruk-garuk kepala dan ada sampah di kode dengan aktor yang saling berlangganan, namun pada akhirnya saya berhasil menghasilkan arsitektur yang agak sederhana dan elegan. Kode di dalam masing-masing aktor dapat dianggap single-threaded; ketika sebuah aktor mogok, acca memulai ulang - hasilnya adalah sistem yang cukup toleran terhadap kesalahan.

9 Agustus

Saya menambahkan ke proyek scala-scrapper untuk mem-parsing halaman html dari Habr (untuk mengeluarkan informasi seperti rating artikel, jumlah bookmark, dll.).

Dan Kucing. Yang ada di batu.

Bot Telegram untuk pilihan artikel yang dipersonalisasi dari Habr

Saya kemudian membaca buku tentang database terdistribusi, saya menyukai ide CRDT (tipe data replikasi bebas konflik, https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type, habr), jadi saya memposting kelas tipe semigrup komutatif untuk informasi tentang artikel di Habré.

Sebenarnya, idenya sangat sederhana - kami memiliki penghitung yang berubah secara monoton. Jumlah promosi secara bertahap bertambah, begitu pula jumlah plusnya (dan juga jumlah minusnya). Jika saya memiliki dua versi informasi tentang sebuah artikel, maka saya dapat “menggabungkannya menjadi satu” - status penghitung yang lebih besar dianggap lebih relevan.

Semigrup berarti dua objek dengan informasi tentang suatu artikel dapat digabungkan menjadi satu. Komutatif artinya bisa menggabungkan A + B dan B + A, hasilnya tidak tergantung urutan, dan pada akhirnya tetap versi terbaru. Omong-omong, ada juga asosiatif di sini.

Misalnya, seperti yang direncanakan, rss setelah penguraian memberikan informasi yang sedikit lemah tentang artikel tersebut - tanpa metrik seperti jumlah penayangan. Seorang aktor khusus kemudian mengambil informasi tentang artikel tersebut dan berlari ke halaman html untuk memperbaruinya dan menggabungkannya dengan versi lama.

Secara umum, seperti di akka, hal ini tidak diperlukan, Anda cukup menyimpan updateDate untuk artikel tersebut dan mengambil yang lebih baru tanpa penggabungan apa pun, tetapi jalan petualangan membawa saya.

12 Agustus

Saya mulai merasa lebih bebas dan, hanya untuk bersenang-senang, saya menjadikan setiap obrolan sebagai aktor yang terpisah. Secara teoritis, seorang aktor itu sendiri memiliki berat sekitar 300 byte dan dapat dibuat dalam jutaan, jadi ini adalah pendekatan yang sepenuhnya normal. Bagi saya, solusinya ternyata cukup menarik:

Salah satu aktornya adalah jembatan antara server telegram dan sistem pesan di Akka. Dia hanya menerima pesan dan mengirimkannya ke aktor obrolan yang diinginkan. Aktor obrolan dapat mengirimkan sesuatu kembali sebagai tanggapan - dan itu akan dikirim kembali ke telegram. Yang sangat nyaman adalah aktor ini ternyata sesederhana mungkin dan hanya berisi logika untuk menanggapi pesan. Ngomong-ngomong, informasi tentang artikel baru datang ke setiap obrolan, tapi sekali lagi saya tidak melihat ada masalah dalam hal ini.

Secara umum, bot sudah berfungsi, merespons pesan, menyimpan daftar artikel yang dikirimkan ke pengguna, dan saya sudah mengira bot itu hampir siap. Saya perlahan menambahkan fitur kecil seperti menormalkan nama penulis dan tag (mengganti “sd f” dengan “s_d_f”).

Hanya ada satu hal yang tersisa kecil tapi — negara tidak disimpan di mana pun.

Semuanya tidak beres

Anda mungkin memperhatikan bahwa saya kebanyakan menulis bot sendirian. Jadi, peserta kedua terlibat dalam pengembangan, dan perubahan berikut muncul pada kode:

  • MongoDB tampaknya menyimpan status. Pada saat yang sama, log dalam proyek rusak, karena untuk beberapa alasan Monga mulai mengirim spam dan beberapa orang mematikannya secara global.
  • Aktor jembatan di Telegram berubah tanpa bisa dikenali dan mulai mengurai pesan sendiri.
  • Aktor untuk obrolan tanpa ampun disingkirkan, dan sebagai gantinya mereka digantikan oleh aktor yang menyembunyikan semua informasi tentang semua obrolan sekaligus. Untuk setiap bersin, aktor ini mendapat masalah. Ya, seperti ketika memperbarui informasi tentang sebuah artikel, mengirimkannya ke semua pelaku obrolan itu sulit (kami seperti Google, jutaan pengguna menunggu satu juta artikel di obrolan untuk masing-masingnya), tetapi setiap kali obrolan diperbarui, itu normal untuk pergi ke Monga. Seperti yang saya sadari kemudian, logika kerja obrolan juga sepenuhnya terputus dan sebagai gantinya muncul sesuatu yang tidak berfungsi.
  • Tidak ada jejak tersisa dari kelas tipe.
  • Beberapa logika yang tidak sehat telah muncul dalam diri para aktor yang saling berlangganan, sehingga mengarah pada kondisi ras.
  • Struktur data dengan bidang tipe Option[Int] berubah menjadi Int dengan nilai default magis seperti -1. Belakangan saya menyadari bahwa mongoDB menyimpan json dan tidak ada salahnya menyimpannya di sana Option baik, atau setidaknya parsing -1 sebagai Tidak Ada, tetapi pada saat itu saya tidak mengetahui hal ini dan percaya bahwa "begitulah seharusnya". Saya tidak menulis kode itu, dan saya tidak repot-repot mengubahnya untuk saat ini.
  • Saya menemukan bahwa alamat IP publik saya cenderung berubah, dan setiap kali saya harus menambahkannya ke daftar putih Mongo. Saya meluncurkan bot secara lokal, Monga ada di suatu tempat di server Monga sebagai sebuah perusahaan.
  • Tiba-tiba, normalisasi tag dan format pesan untuk telegram menghilang. (Hmm, mengapa itu terjadi?)
  • Saya suka bahwa status bot disimpan dalam database eksternal, dan ketika dimulai ulang, bot terus berfungsi seolah-olah tidak terjadi apa-apa. Namun, ini adalah satu-satunya nilai tambah.

Orang kedua tidak terburu-buru, dan semua perubahan ini muncul dalam satu tumpukan besar di awal September. Saya tidak langsung menghargai skala kehancuran yang diakibatkannya dan mulai memahami cara kerja database, karena... Saya belum pernah berurusan dengan mereka sebelumnya. Baru kemudian saya menyadari berapa banyak kode kerja yang dipotong dan berapa banyak bug yang ditambahkan sebagai gantinya.

September

Awalnya saya pikir akan berguna jika menguasai Monga dan melakukannya dengan baik. Kemudian saya perlahan mulai memahami bahwa mengatur komunikasi dengan database juga merupakan seni di mana Anda bisa membuat banyak balapan dan hanya membuat kesalahan. Misalnya, jika pengguna menerima dua pesan seperti /subscribe - dan sebagai tanggapan terhadap masing-masing pesan tersebut kami akan membuat entri di tabel, karena pada saat memproses pesan tersebut pengguna belum berlangganan. Saya curiga komunikasi dengan Monga dalam bentuknya saat ini tidak ditulis dengan cara terbaik. Misalnya, pengaturan pengguna dibuat pada saat dia mendaftar. Jika dia mencoba mengubahnya sebelum berlangganan... bot tidak merespons apa pun, karena kode di aktor masuk ke database untuk pengaturan, tidak menemukannya dan macet. Ketika ditanya mengapa tidak membuat pengaturan sesuai kebutuhan, saya mengetahui bahwa tidak perlu mengubahnya jika pengguna belum berlangganan... Sistem pemfilteran pesan dibuat entah bagaimana tidak jelas, dan bahkan setelah melihat lebih dekat kodenya saya bisa tidak mengerti apakah awalnya dimaksudkan seperti itu atau ada kesalahan di sana.

Tidak ada daftar artikel yang dikirimkan ke obrolan, malah disarankan agar saya menulisnya sendiri. Ini mengejutkan saya - secara umum, saya tidak menentang menyeret segala macam hal ke dalam proyek, tetapi akan logis bagi orang yang membawa hal-hal ini dan mengacaukannya. Tapi tidak, peserta kedua sepertinya menyerah dalam segala hal, tetapi mengatakan bahwa daftar di dalam obrolan dianggap sebagai solusi yang buruk, dan perlu membuat tanda dengan kejadian seperti “artikel y dikirim ke pengguna x.” Kemudian, jika pengguna meminta untuk mengirim artikel baru, maka perlu mengirim permintaan ke database, yang akan memilih acara yang terkait dengan pengguna dari acara tersebut, juga mendapatkan daftar artikel baru, memfilternya, mengirimkannya ke pengguna dan membuang kejadian tentang ini kembali ke database.

Peserta kedua terbawa ke suatu tempat menuju abstraksi, ketika bot tidak hanya menerima artikel dari Habr dan dikirim tidak hanya ke telegram.

Saya entah bagaimana mengimplementasikan acara dalam bentuk tanda terpisah untuk paruh kedua bulan September. Ini tidak optimal, tapi setidaknya bot mulai bekerja dan mulai mengirimi saya artikel lagi, dan perlahan-lahan saya mengetahui apa yang terjadi di kode tersebut.

Sekarang Anda dapat kembali ke awal dan mengingat bahwa repositori ini awalnya bukan saya buat. Apa yang bisa terjadi seperti ini? Permintaan penarikan saya ditolak. Ternyata saya memiliki kode redneck, saya tidak tahu cara bekerja dalam tim, dan saya harus memperbaiki bug pada kurva implementasi saat ini, dan tidak menyempurnakannya ke kondisi yang dapat digunakan.

Saya kesal dan melihat riwayat komit dan jumlah kode yang ditulis. Saya melihat momen-momen yang awalnya ditulis dengan baik, dan kemudian dipecah kembali...

Persetan

Saya ingat artikel itu Anda bukan Google.

Saya pikir tidak ada seorang pun yang membutuhkan ide tanpa implementasi. Saya pikir saya ingin memiliki bot yang berfungsi, yang akan bekerja dalam satu salinan di satu komputer sebagai program java sederhana. Saya tahu bahwa bot saya akan bekerja selama berbulan-bulan tanpa memulai ulang, karena saya sudah pernah menulis bot seperti itu sebelumnya. Jika tiba-tiba jatuh dan tidak mengirimkan artikel lain kepada pengguna, langit tidak akan jatuh ke tanah dan tidak ada bencana besar yang akan terjadi.

Mengapa saya memerlukan Docker, mongoDB, dan perangkat lunak "serius" lainnya jika kodenya tidak berfungsi atau tidak berfungsi?

Saya membagi proyek dan melakukan semua yang saya inginkan.

Bot Telegram untuk pilihan artikel yang dipersonalisasi dari Habr

Sekitar waktu yang sama, saya berganti pekerjaan dan waktu luang menjadi sangat berkurang. Pagi harinya saya bangun tepat di kereta, sore harinya saya pulang terlambat dan tidak ingin berbuat apa-apa lagi. Saya tidak melakukan apa pun untuk sementara waktu, kemudian keinginan untuk menyelesaikan bot menguasai saya, dan saya mulai menulis ulang kode secara perlahan saat saya mengemudi ke tempat kerja di pagi hari. Saya tidak akan mengatakan bahwa itu produktif: duduk di kereta yang bergetar dengan laptop di pangkuan Anda dan melihat stack overflow dari ponsel Anda sangatlah tidak nyaman. Namun, waktu yang dihabiskan untuk menulis kode berlalu begitu saja tanpa disadari, dan proyek mulai perlahan-lahan bergerak menuju kondisi kerja.

Di benak saya ada cacing keraguan yang ingin menggunakan mongoDB, tapi menurut saya selain kelebihan penyimpanan negara yang "dapat diandalkan", ada juga kelemahan yang nyata:

  • Basis data menjadi titik kegagalan lainnya.
  • Kode ini menjadi lebih kompleks, dan saya memerlukan waktu lebih lama untuk menulisnya.
  • Kode menjadi lambat dan tidak efisien; alih-alih mengubah objek di memori, perubahan tersebut dikirim ke database dan, jika perlu, ditarik kembali.
  • Ada batasan pada jenis penyimpanan acara dalam tabel terpisah, yang dikaitkan dengan kekhasan database.
  • Versi uji coba Monga memiliki beberapa keterbatasan, dan jika Anda mengalaminya, Anda harus meluncurkan dan mengkonfigurasi Monga pada sesuatu.

Saya hentikan monga, sekarang status bot hanya disimpan di memori program dan dari waktu ke waktu disimpan ke file dalam bentuk json. Mungkin di kolom komentar mereka akan menulis bahwa saya salah, di sinilah database harus digunakan, dll. Tapi ini proyek saya, pendekatan dengan file tersebut sesederhana mungkin dan bekerja secara transparan.

Membuang nilai ajaib seperti -1 dan mengembalikan nilai normal Option, menambahkan penyimpanan tabel hash dengan artikel yang dikirim kembali ke objek dengan informasi obrolan. Menambahkan penghapusan informasi tentang artikel yang lebih lama dari lima hari, agar tidak menyimpan semuanya. Saya membawa logging ke status berfungsi - log ditulis dalam jumlah yang wajar ke file dan konsol. Menambahkan beberapa perintah admin seperti menyimpan status atau memperoleh statistik seperti jumlah pengguna dan artikel.

Memperbaiki banyak hal kecil: misalnya, untuk artikel, jumlah penayangan, suka, tidak suka, dan komentar pada saat melewati filter pengguna kini ditunjukkan. Secara umum, sungguh mengejutkan betapa banyak hal kecil yang harus diperbaiki. Saya membuat daftar, mencatat semua “kejanggalan” di sana dan memperbaikinya sejauh mungkin.

Misalnya, saya menambahkan kemampuan untuk mengatur semua pengaturan secara langsung dalam satu pesan:

/subscribe
/rating +20
/author a -30
/author s -20
/author p +9000
/tag scala 20
/tag akka 50

Dan tim lain /settings menampilkannya persis dalam formulir ini, Anda dapat mengambil teks darinya dan mengirimkan semua pengaturan ke teman.
Kelihatannya sepele, tapi ada puluhan nuansa serupa.

Pemfilteran artikel diterapkan dalam bentuk model linier sederhana - pengguna dapat menetapkan peringkat tambahan untuk penulis dan tag, serta nilai ambang batas. Jika jumlah rating penulis, rating rata-rata untuk tag, dan rating artikel sebenarnya lebih besar dari nilai ambang batas, maka artikel tersebut akan ditampilkan kepada pengguna. Anda dapat meminta artikel kepada bot dengan perintah /baru, atau berlangganan bot dan bot akan mengirimkan artikel dalam pesan pribadi kapan saja sepanjang hari.

Secara umum, saya punya ide untuk setiap artikel untuk mengeluarkan lebih banyak fitur (hub, jumlah komentar, bookmark, dinamika perubahan peringkat, jumlah teks, gambar dan kode dalam artikel, kata kunci), dan menunjukkan kepada pengguna oke/ tidak oke pilih di bawah setiap artikel dan latih model untuk setiap pengguna, tapi saya terlalu malas.

Selain itu, logika kerjanya tidak akan begitu jelas. Sekarang saya dapat secara manual menetapkan peringkat +9000 untukpatientZero dan dengan peringkat ambang +20 saya dijamin akan menerima semua artikelnya (kecuali, tentu saja, saya menetapkan -100500 untuk beberapa tag).

Arsitektur akhirnya ternyata cukup sederhana:

  1. Aktor yang menyimpan status semua obrolan dan artikel. Ia memuat statusnya dari file di disk dan menyimpannya kembali dari waktu ke waktu, setiap kali ke file baru.
  2. Seorang aktor yang mengunjungi RSS feed dari waktu ke waktu, mempelajari artikel baru, melihat link, mem-parsing, dan mengirimkan artikel tersebut ke aktor pertama. Selain itu, terkadang meminta daftar artikel dari aktor pertama, memilih artikel yang tidak lebih dari tiga hari, tetapi sudah lama tidak diperbarui, dan memperbaruinya.
  3. Seorang aktor yang berkomunikasi dengan telegram. Saya masih membawa penguraian pesan sepenuhnya di sini. Dengan cara yang bersahabat, saya ingin membaginya menjadi dua - sehingga yang satu mem-parsing pesan masuk, dan yang kedua menangani masalah transportasi seperti mengirim ulang pesan yang belum terkirim. Sekarang tidak ada pengiriman ulang, dan pesan yang tidak sampai karena kesalahan akan hilang begitu saja (kecuali dicatat di log), tetapi sejauh ini tidak menimbulkan masalah. Mungkin masalah akan muncul jika sekelompok orang berlangganan bot dan saya mencapai batas pengiriman pesan).

Yang saya suka adalah berkat akka, jatuhnya aktor 2 dan 3 secara umum tidak mempengaruhi kinerja bot. Mungkin beberapa artikel tidak diperbarui tepat waktu atau beberapa pesan tidak sampai ke telegram, tetapi akun tersebut memulai ulang aktor dan semuanya terus berfungsi. Saya menyimpan informasi bahwa artikel tersebut ditampilkan kepada pengguna hanya ketika aktor telegram menjawab bahwa dia telah berhasil menyampaikan pesan. Hal terburuk yang mengancam saya adalah mengirim pesan beberapa kali (jika terkirim, tetapi konfirmasinya hilang). Pada prinsipnya, jika aktor pertama tidak menyimpan keadaan di dalam dirinya, tetapi berkomunikasi dengan suatu database, maka ia juga bisa jatuh tanpa disadari dan hidup kembali. Saya juga dapat mencoba akka persistence untuk memulihkan kondisi aktor, namun implementasi saat ini cocok untuk saya karena kesederhanaannya. Bukan karena kode saya sering error - sebaliknya, saya berusaha keras untuk menjadikannya tidak mungkin. Tapi hal buruk terjadi, dan kemampuan untuk memecah program menjadi aktor-aktor yang terisolasi tampak sangat nyaman dan praktis bagi saya.

Saya menambahkan lingkaran-ci sehingga jika kodenya rusak, Anda akan langsung mengetahuinya. Minimal, ini berarti kode telah berhenti dikompilasi. Awalnya saya ingin menambahkan travis, tetapi itu hanya menampilkan proyek saya tanpa fork. Secara umum kedua hal ini dapat digunakan secara bebas di repositori terbuka.

Hasil

Ini sudah bulan November. Botnya tertulis, saya telah menggunakannya selama dua minggu terakhir dan saya menyukainya. Jika Anda memiliki ide untuk perbaikan, tulislah. Saya tidak melihat gunanya memonetisasinya - biarkan saja berfungsi dan kirimkan artikel menarik.

а а ота: https://t.me/HabraFilterBot
Github: https://github.com/Kright/habrahabr_reader

Kesimpulan kecil:

  • Bahkan proyek kecil pun bisa memakan banyak waktu.
  • Anda bukan Google. Tidak ada gunanya menembak burung pipit dari meriam. Solusi sederhana mungkin juga berhasil.
  • Proyek kesayangan sangat bagus untuk bereksperimen dengan teknologi baru.
  • Bot Telegram ditulis dengan cukup sederhana. Jika bukan karena “kerja tim” dan eksperimen dengan teknologi, bot tersebut akan selesai ditulis dalam satu atau dua minggu.
  • Model aktor adalah hal menarik yang cocok dengan kode multi-threading dan toleransi kesalahan.
  • Saya rasa saya mengerti mengapa komunitas open source menyukai fork.
  • Basis data bagus karena status aplikasi tidak lagi bergantung pada aplikasi mogok/restart, tetapi bekerja dengan basis data memperumit kode dan menerapkan batasan pada struktur data.

Sumber: www.habr.com

Tambah komentar