ไลบรารี Haskell ที่ดีที่สุดในการใช้งานโปรแกรมคืออะไร [ปิด]


115

หากฉันจะนำโปรแกรมไปใช้ในการผลิตมีหลายสิ่งที่ฉันต้องการให้โปรแกรมนั้นทำเพื่อที่จะพิจารณาว่า "ใช้งานได้" นั่นคือการทำงานและบำรุงรักษาด้วยวิธีที่วัดผลได้และตรวจสอบได้โดยทั้งวิศวกรและเจ้าหน้าที่ฝ่ายปฏิบัติการ สำหรับวัตถุประสงค์ของฉันโปรแกรมที่ดำเนินการจะต้อง:

  • สามารถบันทึกได้หลายระดับ (เช่นการดีบักคำเตือน ฯลฯ )
  • สามารถรวบรวมและแบ่งปันเมตริก / สถิติเกี่ยวกับประเภทของงานที่โปรแกรมกำลังทำและระยะเวลาที่งานนั้นใช้ ตามหลักการแล้วเมตริกที่รวบรวมจะมีอยู่ในรูปแบบที่เข้ากันได้กับเครื่องมือการตรวจสอบที่ใช้กันทั่วไปเช่นGangliaหรืออาจเป็นแบบ munged ก็ได้
  • สามารถกำหนดค่าได้โดยดีอย่างยิ่งผ่านระบบที่อนุญาตให้คุณสมบัติที่กำหนดค่าไว้ในโปรแกรมที่รันอยู่เพื่ออัปเดตโดยไม่ต้องรีสตาร์ทโปรแกรมดังกล่าว
  • สามารถปรับใช้กับเซิร์ฟเวอร์ระยะไกลด้วยวิธีที่ทำซ้ำได้

ในโลกของ Scala มีห้องสมุดที่ดีสำหรับจัดการกับข้อกำหนดอย่างน้อยสามข้อแรก ตัวอย่าง:

สำหรับการปรับใช้แนวทางหนึ่งที่ใช้ในโลกของ Scala คือการรวมไบต์โค้ดและไลบรารีที่ประกอบด้วยโปรแกรมของตนเข้าด้วยกันเช่นแอสเซมบลี - sbtจากนั้นดันบันเดิลผลลัพธ์ ("fat JAR") ไปยังเซิร์ฟเวอร์ระยะไกลด้วยเครื่องมือเช่นCapistranoที่รันคำสั่งแบบขนานบน SSH นี่ไม่ใช่ปัญหาที่จำเป็นต้องใช้เครื่องมือเฉพาะภาษา แต่ฉันสงสัยว่ามีเครื่องมือดังกล่าวอยู่ในชุมชน Haskell หรือไม่

อาจมีห้องสมุดของ Haskell ที่มีลักษณะที่ฉันได้อธิบายไว้ข้างต้น ฉันต้องการทราบว่าห้องสมุดใดที่มีให้บริการ "ดีที่สุด" นั่นคือซึ่งเป็นผู้ใหญ่มากที่สุดได้รับการดูแลอย่างดีมักใช้ในชุมชน Haskell และเป็นตัวอย่างของแนวทางปฏิบัติที่ดีที่สุดของ Haskell

หากมีไลบรารีเครื่องมือหรือแนวทางปฏิบัติอื่น ๆ เกี่ยวกับการสร้างโค้ด Haskell "พร้อมใช้งานจริง" ฉันก็อยากทราบข้อมูลเหล่านี้เช่นกัน


1
สัญลักษณ์แสดงหัวข้อย่อยที่สี่อาจทำให้เกิดปัญหาได้เนื่องจาก Haskell รวบรวมเป็นแบบเนทีฟ คุณสามารถลองคอมไพล์แบบคงที่ซึ่งอาจใช้งานได้หรือไม่ก็ได้ แต่ในทางที่ดีคุณจะมีสภาพแวดล้อมที่คล้ายกันบนเซิร์ฟเวอร์ที่ใช้งานจริงมากกว่าบนเซิร์ฟเวอร์การพัฒนา Cabal-dev เป็นสภาพแวดล้อมแบบแซนด์บ็อกซ์ซึ่งอาจเหมาะสำหรับการถ่ายโอนไปยังเครื่องอื่น ถึงอย่างนั้นก็ต้องใช้ไลบรารีฐานอย่างน้อยเพื่อติดตั้งบนเครื่องเป้าหมาย
Masse

1
เกี่ยวกับเครื่องมือและเทคนิคอื่น ๆ คำถาม SO นี้มีภาพรวม: stackoverflow.com/questions/3077866/…
Don Stewart

1
อีกอย่างหนึ่ง - คุณสามารถเข้าถึงบนระบบ * nix ซึ่งเป็นสถิติกระบวนการและข้อมูลเมตาจำนวนมากได้โดยตรงผ่านระบบไฟล์ / proc ดังนั้นหากคุณเขียนกิจวัตรสองสามอย่างเพื่อไตร่ตรองสิ่งนั้นจะช่วยทดแทนการขาด hooks โดยตรงในรันไทม์
sclv

1
การปรับใช้ไบนารีนั้นทำได้ง่ายตราบเท่าที่คุณสร้างบนสภาพแวดล้อมเดียวกัน (คุณควรมีเซิร์ฟเวอร์การจัดเตรียมหากคอมพิวเตอร์ของคุณเป็นสถาปัตยกรรมอื่น) จากนั้นคุณสามารถ rsync ไบนารีและไฟล์ภายนอกใด ๆ ไม่มีไลบรารี ssh สำหรับ haskell สำหรับการรันคำสั่งรีสตาร์ทโดยอัตโนมัติ แต่คุณสามารถใช้ capistrano ได้
Greg Weber

1
@tchrist เขาใช้เวลาที่เหลือของย่อหน้าแรกและรายการสัญลักษณ์แสดงหัวข้อย่อยทันทีหลังจากคำว่าปฏิบัติการอธิบายความหมายเป็นภาษาอังกฤษธรรมดา
Will McCutchen

คำตอบ:


54

นี่เป็นคำถามที่ดีมาก! นี่เป็นการตัดครั้งแรก

สามารถบันทึกได้หลายระดับ (เช่นการดีบักคำเตือน ฯลฯ )

hsloggerเป็นเฟรมเวิร์กการบันทึกที่ได้รับความนิยมมากที่สุด

สามารถรวบรวมและแบ่งปันเมตริก / สถิติเกี่ยวกับประเภทของงานที่โปรแกรมกำลังทำและระยะเวลาที่งานนั้นใช้ ตามหลักการแล้วเมตริกที่รวบรวมไว้จะมีให้ในรูปแบบที่เข้ากันได้กับเครื่องมือตรวจสอบที่ใช้กันทั่วไปเช่น Ganglia หรืออาจเป็นแบบ munged ก็ได้

ฉันไม่ทราบถึงเครื่องมือการรายงานมาตรฐานใด ๆ อย่างไรก็ตามการแยกรายงานจาก+RTS -sสตรีม (หรือผ่านแฟล็กเอาต์พุตการทำโปรไฟล์) เป็นสิ่งที่ฉันเคยทำในอดีต

$ ./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

คุณสามารถรับสิ่งนี้ในรูปแบบที่เครื่องอ่านได้ด้วย:

$ ./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")
 ]

ตามหลักการแล้วคุณสามารถเชื่อมต่อกับรันไทม์ GHC ที่กำลังทำงานอยู่บนซ็อกเก็ตและดูสถิติ GC เหล่านี้ในเชิงโต้ตอบได้ แต่ตอนนี้ไม่ใช่เรื่องง่ายสุด ๆ (ต้องการการเชื่อมโยง FFI กับอินเทอร์เฟซ "rts / Stats.h") คุณสามารถแนบไปกับกระบวนการโดยใช้ThreadScopeและตรวจสอบ GC และลักษณะการทำงานของเธรด

แฟล็กที่คล้ายกันจะพร้อมใช้งานสำหรับการเพิ่มเวลาบันทึกเวลาและการทำโปรไฟล์พื้นที่ซึ่งสามารถใช้สำหรับการมอนิเตอร์ (เช่นกราฟเหล่านี้สามารถสร้างขึ้นทีละน้อย)

hpcรวบรวมสถิติจำนวนมากเกี่ยวกับการทำงานของโปรแกรมผ่านTixประเภทของโปรแกรมและผู้คนได้เขียนเครื่องมือเพื่อเข้าสู่ระบบโดยแบ่งเวลาว่าโค้ดใดกำลังเรียกใช้งาน

สามารถกำหนดค่าได้โดยดีอย่างยิ่งผ่านระบบที่อนุญาตให้คุณสมบัติที่กำหนดค่าไว้ในโปรแกรมที่รันอยู่เพื่ออัปเดตโดยไม่ต้องรีสตาร์ทโปรแกรมดังกล่าว

มีเครื่องมือมากมายสำหรับสิ่งนี้คุณสามารถทำการรีโหลดสถานะแบบ xmonad ได้ หรือเลื่อนขึ้นไปยังโค้ด hotswapping ผ่านpluginsแพ็คเกจ * หรือhint. บางส่วนเป็นการทดลองมากกว่าแบบอื่น ๆ

การปรับใช้ที่ทำซ้ำได้

Galois เพิ่งเปิดตัวcabal-devซึ่งเป็นเครื่องมือสำหรับการสร้างที่ทำซ้ำได้ (เช่นการอ้างอิงจะถูกกำหนดขอบเขตและควบคุม)


6
แพ็คเกจ dyre ควรจะแยกการโหลดสถานะแบบ xmonad เป็นนามธรรมดังนั้นฉันคิดว่าควรกล่าวถึงเป็นพิเศษ อย่างไรก็ตามมันเชื่อมโยงการคอมไพล์ใหม่และการปรับใช้ใหม่เข้าด้วยกันดังนั้นจึงเป็นเรื่องเกี่ยวกับการเปลี่ยนแปลงบนเครื่องด้วย toolchain ทั้งหมด สำหรับ redeploys ระยะไกลคุณต้องการบางสิ่งบางอย่างเช่นสถานะกรดแม้ว่ามันจะหนักไปหน่อยสำหรับรสนิยมของฉัน ฉันมีนามธรรม mvar ถาวรซึ่งมีการรับประกันที่อ่อนแอกว่า แต่คุณสามารถปฏิบัติเหมือน MVar ธรรมดาที่มีการเติมข้อมูลอย่างน่าอัศจรรย์ในการเปิดตัวไบนารีแต่ละครั้งพร้อมกับข้อมูลสุดท้ายที่เก็บไว้
sclv

2
นอกจากนี้EventLogเฟรมเวิร์กการบันทึกใหม่ของ GHC (ใช้+RTS -lที่รันไทม์) จะสตรีมเอาต์พุตไปยังไฟล์ซึ่งสามารถมองเห็นได้ด้วยเครื่องมือใด ๆ ที่อ่านรูปแบบ eventlog
Don Stewart

2
โปรแกรมจะปล่อยบันทึกของเหตุการณ์เช่นนี้galois.com/~dons/tmp/A.event.log - ซึ่งอาจจะมองเห็น - i.imgur.com/QAe6r.png ฉันนึกภาพออกว่าสร้างเครื่องมือตรวจสอบอื่น ๆ ที่ด้านบนของรูปแบบนี้
Don Stewart

2
นอกจากนี้โปรดทราบว่าเครื่องมือทำโปรไฟล์จำนวนมากเหมาะสำหรับการทดสอบ แต่ไม่มากสำหรับโค้ดการผลิต ยกเว้นค่าใช้จ่ายตัวอย่างเช่น -prof สามารถใช้ได้กับโปรเซสเซอร์ตัวเดียวเท่านั้น
sclv

9
  • เกี่ยวกับการกำหนดค่าฉันพบว่า ConfigFile มีประโยชน์สำหรับโครงการของฉัน ฉันใช้มันสำหรับภูตทั้งหมดของฉันในการผลิต มันไม่อัปเดตโดยอัตโนมัติ
  • ฉันใช้ cabal-dev เพื่อสร้างงานสร้างที่ทำซ้ำได้ในสภาพแวดล้อมต่างๆ (ในพื้นที่, ผู้พัฒนา, เพื่อนร่วมงานในพื้นที่) cabal-dev เป็นสิ่งที่ขาดไม่ได้โดยเฉพาะอย่างยิ่งสำหรับความสามารถในการรองรับไลบรารีเวอร์ชันท้องถิ่นที่ได้รับการแก้ไขแล้วภายในไดเรกทอรีโครงการ
  • สำหรับสิ่งที่คุ้มค่าฉันจะไปกับการโหลดสถานะแบบ xmonad ความบริสุทธิ์ของ Haskell ทำให้เรื่องนี้เป็นเรื่องเล็กน้อย การโยกย้ายเป็นปัญหา แต่อย่างไรก็ตาม ฉันทดลองใช้ hsplugins และคำใบ้สำหรับ IRCd ของฉันและในกรณีก่อนหน้านี้มีปัญหารันไทม์ GHC และในช่วงหลังเกิดข้อผิดพลาดในการแบ่งส่วน ฉันออกจากสาขาบน Github เพื่อทำการชันสูตรพลิกศพในภายหลัง: https://github.com/chrisdone/hulk

ตัวอย่าง ConfigFile:

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

9

ฉันจะสะท้อนทุกสิ่งที่ดอนพูดและเพิ่มคำแนะนำทั่วไปเล็กน้อย

ตัวอย่างเช่นเครื่องมือและไลบรารีเพิ่มเติมสองรายการที่คุณอาจต้องการพิจารณา:

  • QuickCheckสำหรับการทดสอบตามคุณสมบัติ
  • คำใบ้เป็นเวอร์ชันขยายของ-Wall

ทั้งสองมีเป้าหมายที่คุณภาพโค้ด

ในการฝึกเขียนโค้ดให้หลีกเลี่ยง Lazy IO หากคุณจำเป็นต้องสตรีมมิ่ง IO แล้วไปกับหนึ่งในห้องสมุด iteratee เช่นการแจงนับ หากคุณดูHackageคุณจะเห็นไลบรารีเช่น http-enumerator ที่ใช้รูปแบบตัวแจงนับสำหรับคำขอ http

สำหรับการเลือกไลบรารีในการแฮ็กบางครั้งอาจช่วยดูว่ามีกี่แพ็คเกจขึ้นอยู่กับบางสิ่ง ดูการอ้างอิงย้อนกลับของแพ็คเกจได้อย่างง่ายดายที่คุณสามารถใช้เว็บไซต์นี้ซึ่งสะท้อนถึงการแฮ็ก:

หากแอปพลิเคชันของคุณต้องวนซ้ำอย่างแน่นหนาเช่นเว็บเซิร์ฟเวอร์ที่จัดการคำขอจำนวนมากความเกียจคร้านอาจเป็นปัญหาในรูปแบบของการรั่วไหลของพื้นที่ บ่อยครั้งสิ่งนี้เป็นเรื่องของการเพิ่มคำอธิบายประกอบที่เข้มงวดในตำแหน่งที่เหมาะสม การสร้างโปรไฟล์ประสบการณ์และหลักในการอ่านเป็นเทคนิคหลักที่ฉันรู้ในการต่อสู้กับสิ่งประเภทนี้ ที่ดีที่สุดของการอ้างอิงโปรไฟล์ฉันรู้ว่าเป็นบทที่ 25ของโลกจริง Haskell

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.