Apa perpustakaan Haskell terbaik untuk menjalankan program? [Tutup]

115

Jika saya akan memasukkan sebuah program ke dalam produksi, ada beberapa hal yang saya perlu program itu lakukan untuk menganggapnya "dioperasionalkan" - yaitu, berjalan dan dapat dipelihara dengan cara yang terukur dan dapat diverifikasi oleh insinyur dan staf operasi. Untuk tujuan saya, program yang dioperasionalkan harus:

  • Mampu masuk di berbagai level (mis: debug, peringatan, dll.).
  • Mampu mengumpulkan dan berbagi metrik / statistik tentang jenis pekerjaan yang dilakukan program dan berapa lama waktu yang dibutuhkan untuk pekerjaan itu. Idealnya, metrik yang dikumpulkan tersedia dalam format yang kompatibel dengan alat pemantauan yang umum digunakan seperti Ganglia , atau bisa sangat disesuaikan.
  • Dapat dikonfigurasi, idealnya melalui sistem yang memungkinkan properti yang dikonfigurasi dalam menjalankan program diperbarui tanpa memulai ulang program tersebut.
  • Dapat diterapkan ke server jarak jauh dengan cara yang berulang.

Di dunia Scala, ada perpustakaan yang bagus untuk menangani setidaknya tiga persyaratan pertama. Contoh:

Adapun penerapan, salah satu pendekatan yang diambil di dunia Scala adalah menggabungkan bersama bytecode dan pustaka yang membentuk program seseorang dengan sesuatu seperti assembly-sbt , lalu mendorong bundel yang dihasilkan ("JAR gemuk") ke server jarak jauh dengan alat seperti Capistrano yang menjalankan perintah secara paralel melalui SSH. Ini bukan masalah yang memerlukan alat khusus bahasa, tapi saya penasaran apakah alat semacam itu ada di komunitas Haskell.

Mungkin ada perpustakaan Haskell yang menyediakan ciri-ciri yang saya jelaskan di atas. Saya ingin tahu perpustakaan mana yang dianggap "terbaik"; yaitu, yang paling matang, terpelihara dengan baik, biasa digunakan dalam komunitas Haskell, dan contoh praktik terbaik Haskell.

Jika ada pustaka, alat, atau praktik lain seputar pembuatan kode Haskell "siap produksi", saya juga ingin mengetahuinya.

Alex Payne
sumber
1
Peluru keempat dapat menyebabkan masalah, karena Haskell dikompilasi ke asli. Anda dapat mencoba mengompilasi secara statis, yang mungkin atau mungkin tidak berfungsi, tetapi secara optimal Anda akan memiliki lingkungan yang serupa di server produksi, daripada di server pengembangan. Cabal-dev adalah lingkungan kotak pasir, yang mungkin cocok untuk ditransfer ke mesin lain. Bahkan kemudian itu akan membutuhkan setidaknya pustaka dasar untuk diinstal pada mesin target.
Misa
1
Mengenai alat dan teknik lain, pertanyaan SO ini memiliki ikhtisar: stackoverflow.com/questions/3077866/…
Don Stewart
1
Satu hal lagi - Anda dapat mengakses pada sistem * nix sejumlah besar statistik proses dan metadata secara langsung melalui sistem file / proc. Jadi, jika Anda menulis beberapa rutinitas untuk mengintrospeksi hal itu, ada baiknya untuk mengganti kurangnya pengait langsung ke dalam runtime.
sclv
1
menerapkan biner itu mudah selama Anda membangun di lingkungan yang sama (Anda harus memiliki server penahapan jika komputer Anda adalah arsitektur yang berbeda). Kemudian Anda dapat melakukan rsync biner dan file eksternal lainnya. Tidak ada pustaka ssh untuk haskell untuk menjalankan perintah restart secara otomatis, tetapi Anda dapat menggunakan capistrano.
Greg Weber
1
@tchrist Dia menghabiskan sisa paragraf pertama dan daftar poin segera setelah kata dioperasionalkan menjelaskan artinya dalam bahasa Inggris sederhana.
Will McCutchen

Jawaban:

54

Ini pertanyaan yang bagus! Ini potongan pertama.

Mampu masuk di berbagai level (mis: debug, peringatan, dll.).

hslogger adalah framework logging yang paling populer.

Mampu mengumpulkan dan berbagi metrik / statistik tentang jenis pekerjaan yang dilakukan program dan berapa lama waktu yang dibutuhkan untuk pekerjaan itu. Idealnya, metrik yang dikumpulkan tersedia dalam format yang kompatibel dengan alat pemantauan yang umum digunakan seperti Ganglia, atau bisa sangat disesuaikan.

Saya tidak mengetahui adanya alat pelaporan standar, namun, mengekstrak laporan dari +RTS -saliran (atau melalui tanda keluaran profil) telah menjadi sesuatu yang telah saya lakukan di masa lalu.

$ ./A +RTS -s
64,952 bytes allocated in the heap
1 MB total memory in use
 %GC time       0.0%  (6.1% elapsed)
 Productivity 100.0% of total user, 0.0% of total elapsed

Anda juga bisa mendapatkan ini dalam format yang dapat dibaca mesin:

$ ./A +RTS -t --machine-readable

 [("bytes allocated", "64952")
 ,("num_GCs", "1")
 ,("average_bytes_used", "43784")
 ,("max_bytes_used", "43784")
 ,("num_byte_usage_samples", "1")
 ,("peak_megabytes_allocated", "1")
 ,("init_cpu_seconds", "0.00")
 ,("init_wall_seconds", "0.00")
 ,("mutator_cpu_seconds", "0.00")
 ,("mutator_wall_seconds", "0.00")
 ,("GC_cpu_seconds", "0.00")
 ,("GC_wall_seconds", "0.00")
 ]

Idealnya Anda dapat melampirkan ke runtime GHC yang berjalan melalui soket dan melihat statistik GC ini secara interaktif, tetapi saat ini itu tidak super mudah (memerlukan FFI yang mengikat ke antarmuka "rts / Stats.h"). Anda dapat melampirkan ke proses menggunakan ThreadScopedan memantau GC dan perilaku threading.

Bendera serupa tersedia untuk pembuatan profil waktu dan ruang tambahan, yang dicatat , yang dapat digunakan untuk pemantauan (misalnya, grafik ini dapat dibuat secara bertahap).

hpcmengumpulkan banyak statistik tentang eksekusi program, melalui Tixtipenya, dan orang-orang telah menulis alat untuk mencatat menurut pembagian waktu kode apa yang sedang dijalankan.

Dapat dikonfigurasi, idealnya melalui sistem yang memungkinkan properti yang dikonfigurasi dalam menjalankan program diperbarui tanpa memulai ulang program tersebut.

Beberapa alat tersedia untuk ini, Anda dapat melakukan pemuatan status gaya xmonad; atau pindah ke hotswapping kode melalui plugins* paket atau hint. Beberapa di antaranya lebih eksperimental daripada yang lain.

Penerapan yang dapat direproduksi

Galois baru-baru ini dirilis cabal-dev, yang merupakan alat untuk melakukan build yang dapat direproduksi (yaitu dependensi dibatasi dan dikontrol).

Don Stewart
sumber
6
Paket dyre seharusnya mengabstraksi pemuatan ulang status gaya xmonad, jadi saya pikir harus disebutkan secara khusus. Namun, ini mengikat kompilasi ulang dan penerapan ulang, jadi ini benar-benar tentang perubahan pada mesin dengan seluruh rantai alat. Untuk redeploys jarak jauh Anda menginginkan sesuatu yang lebih seperti acid-state, meskipun agak berat untuk selera saya. Saya mendapatkan abstraksi mvar persisten ini yang memiliki jaminan lebih lemah, tetapi yang dapat Anda perlakukan seperti MVar biasa yang secara ajaib diisi pada setiap peluncuran biner dengan data terakhir yang dimilikinya.
sclv
2
Juga, EventLogkerangka logging baru GHC (menggunakan +RTS -lsaat runtime) mengalirkan output ke file, yang dapat divisualisasikan dengan alat apa pun yang membaca format eventlog.
Don Stewart
2
Sebuah program akan mengeluarkan log kejadiannya, seperti ini: galois.com/~dons/tmp/A.event.log - yang dapat divisualisasikan sebagai - i.imgur.com/QAe6r.png . Saya bisa membayangkan membangun alat pemantauan lain di atas format ini.
Don Stewart
2
Perhatikan juga bahwa banyak alat pembuatan profil yang bagus untuk pengujian tetapi tidak begitu banyak untuk kode produksi. Selain overhead, -prof misalnya hanya bisa digunakan dengan satu prosesor.
sclv
9
  • Mengenai konfigurasi, saya menemukan ConfigFile berguna untuk proyek saya. Saya menggunakannya untuk semua daemon saya dalam produksi. Itu tidak diperbarui secara otomatis.
  • Saya menggunakan cabal-dev untuk membuat bangunan yang dapat direproduksi di seluruh lingkungan (lokal, dev, kolega-lokal). Benar-benar cabal-dev sangat diperlukan, terutama karena kemampuannya untuk mendukung versi pustaka lokal yang ditambal dalam direktori proyek.
  • Untuk apa nilainya, saya akan menggunakan pemuatan status gaya xmonad. Kemurnian Haskell membuat ini sepele; migrasi adalah sebuah masalah tapi bagaimanapun juga. Saya bereksperimen dengan hsplugins dan petunjuk untuk IRCd saya dan dalam kasus sebelumnya ada masalah runtime GHC, dan yang terakhir adalah kesalahan segmentasi. Saya meninggalkan cabang di Github untuk postmortem nanti: https://github.com/chrisdone/hulk

Contoh ConfigFile:

# Default options
[DEFAULT]
hostname: localhost
# Options for the first file
[file1]
location: /usr/local
user: Fred
Christopher Selesai
sumber
9

Saya akan mengulangi semua yang dikatakan Don dan menambahkan beberapa nasihat umum.

Misalnya, dua alat dan pustaka tambahan yang mungkin ingin Anda pertimbangkan:

  • QuickCheck untuk pengujian berbasis properti
  • hlint sebagai versi tambahan dari-Wall

Keduanya ditargetkan pada kualitas kode.

Sebagai praktik coding, hindari Lazy IO. Jika Anda memerlukan streaming IO, gunakan salah satu library iteratee seperti enumerator . Jika Anda melihat Hackage Anda akan melihat perpustakaan seperti http-enumerator yang menggunakan gaya enumerator untuk permintaan http.

Sedangkan untuk memilih pustaka pada peretasan terkadang dapat membantu untuk melihat berapa banyak paket yang bergantung pada sesuatu. Dengan mudah melihat ketergantungan kebalikan dari sebuah paket, Anda dapat menggunakan situs web ini, yang mencerminkan peretasan:

Jika aplikasi Anda akhirnya melakukan loop ketat, seperti server web yang menangani banyak permintaan, kemalasan bisa menjadi masalah dalam bentuk kebocoran ruang. Seringkali ini adalah masalah menambahkan anotasi ketelitian di tempat yang tepat. Profiling, pengalaman, dan inti membaca adalah teknik utama yang saya ketahui untuk memerangi hal semacam ini. Referensi pembuatan profil terbaik yang saya tahu adalah Bab 25 dari Dunia Nyata Haskell .

Jason Dagit
sumber