2 คะแนน โดย GN⁺ 2024-02-10 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

GrafanaCON 2024: สมัครวันนี้และจองที่นั่งของคุณ!

  • GrafanaCON 2024 เป็นงานอีเวนต์ชุมชนที่ใหญ่ที่สุดของปีนี้ และได้เปิดให้ลงทะเบียนอย่างเป็นทางการแล้ว
  • งานนี้จะมอบประสบการณ์สดแบบเข้าร่วมด้วยตนเองที่อัมสเตอร์ดัมในเดือนเมษายน

ความเห็นของ GN⁺

  • GrafanaCON 2024 เป็นอีเวนต์สำคัญสำหรับผู้ที่สนใจด้านการทำข้อมูลให้เห็นภาพและการมอนิเตอร์ งานนี้จะเป็นพื้นที่ที่ชุมชนผู้ใช้และนักพัฒนา Grafana มารวมตัวกันเพื่อแบ่งปันเทรนด์และเทคโนโลยีล่าสุด
  • งานที่จัดขึ้นที่อัมสเตอร์ดัมครั้งนี้คาดว่าจะเปิดโอกาสให้ผู้เข้าร่วมได้สร้างเครือข่ายและเรียนรู้ พร้อมมีเซสชันต่าง ๆ ที่จะช่วยให้เข้าใจเครื่องมือด้านการวิเคราะห์ข้อมูลและการทำข้อมูลให้เห็นภาพได้ลึกซึ้งยิ่งขึ้น
  • การเปิดรับลงทะเบียนถือเป็นข่าวที่น่าตื่นเต้นสำหรับผู้ใช้ Grafana และเป็นโอกาสอันดีสำหรับผู้เชี่ยวชาญในสายงานนี้ในการเรียนรู้ความรู้ใหม่ ๆ และแลกเปลี่ยนกับเพื่อนร่วมวงการ

1 ความคิดเห็น

 
GN⁺ 2024-02-10
ความคิดเห็นจาก Hacker News
  • The Valid method takes a context (which is optional but has been useful for me in the past) and returns a map. If there is a problem with a field, its name is used as the key, and a human-readable explanation of the issue is set as the value.

    • วิธีการตรวจสอบความถูกต้อง: รับ context แบบทางเลือก และคืนค่าเป็น map ที่ใช้ชื่อฟิลด์ที่มีปัญหาเป็นคีย์ และใช้คำอธิบายปัญหาที่มนุษย์อ่านเข้าใจได้เป็นค่า โดยระบุว่าวิธีนี้เคยมีประโยชน์สำหรับตนในอดีต
  • I used to do this, but ever since reading Lexi Lambda's "Parse, Don't Validate," I've found validators to be much more error-prone than leveraging Go's built-in type checker.

    • แยกวิเคราะห์แทนการตรวจสอบความถูกต้อง: หลังจากได้อ่าน "Parse, Don't Validate" ของ Lexi Lambda ก็รู้สึกว่าการใช้ตัวตรวจสอบความถูกต้องมีโอกาสผิดพลาดมากกว่าการอาศัยตัวตรวจสอบชนิดข้อมูลในตัวของ Go
  • For example, imagine you wanted to defend against the user picking an illegal username. Like you want to make sure the user can't ever specify a username with angle brackets in it.

    • ตัวอย่างการตรวจสอบชื่อผู้ใช้: ลองนึกภาพสถานการณ์ที่ต้องป้องกันไม่ให้ผู้ใช้เลือกชื่อผู้ใช้ที่ไม่ถูกต้อง เช่น ต้องแน่ใจว่าผู้ใช้ไม่สามารถตั้งชื่อที่มีวงเล็บมุมแหลมอยู่ภายในได้
  • With the Validator approach, you have to remember to call the validator on 100% of code paths where the username value comes from an untrusted source.

    • ปัญหาของแนวทางใช้ตัวตรวจสอบความถูกต้อง: ต้องคอยจำให้เรียกตัวตรวจสอบความถูกต้องในทุกเส้นทางของโค้ดที่ค่าชื่อผู้ใช้มาจากแหล่งที่ไม่น่าเชื่อถือ
  • Instead of using a validator, you can do this:

    • เสนอทางเลือกแทนตัวตรวจสอบความถูกต้อง: เสนอวิธีอื่นแทนการใช้ตัวตรวจสอบความถูกต้อง
  • That guarantees that you can never forget to validate the username through any codepath. If you have a Username object, you know that it was validated because there was no other way to create the object.

    • รับประกันความถูกต้องผ่านการสร้างอ็อบเจ็กต์: การตรวจสอบจะเกิดขึ้นตอนสร้างอ็อบเจ็กต์ Username ทำให้ไม่มีทางลืมตรวจสอบผ่านเส้นทางโค้ดใด ๆ ได้ เพราะถ้ามีอ็อบเจ็กต์นี้อยู่ ก็แปลว่ามันผ่านการตรวจสอบมาแล้ว
  • I really like Mat Ryer's work, and I've applied most of the ideas in the 2018 version of this article to all of my Go projects since then.

    • ชื่นชอบงานของ Mat Ryer: ชื่นชอบงานของ Mat Ryer มาก และได้นำแนวคิดส่วนใหญ่จากบทความเวอร์ชันปี 2018 ไปใช้กับทุกโปรเจ็กต์ Go ของตนนับแต่นั้น
  • The one weak spot for me is this aspect:

    • ชี้จุดอ่อน: กล่าวถึงส่วนที่มองว่าเป็นจุดอ่อน
  • This has always felt wrong to me, but I've never been able to figure out a better solution.

    • ยังไม่มีทางออกที่ดีกว่า: รู้สึกมาโดยตลอดว่าสิ่งนี้ไม่ถูกต้อง แต่ก็ยังหาวิธีแก้ที่ดีกว่าไม่ได้
  • It means that a huge chunk of your code has a huge amount of unnecessary shared state.

    • ปัญหาของ shared state: ชี้ว่ามีโค้ดส่วนใหญ่จำนวนมากที่ต้องแบกรับ shared state ที่ไม่จำเป็นอยู่มากมาย
  • I often end up writing HTTP handlers that only need access to a tiny amount of the shared state.

    • HTTP handler กับ shared state: มักลงเอยด้วยการเขียน HTTP handler ที่จริง ๆ แล้วต้องเข้าถึง shared state เพียงเล็กน้อยเท่านั้น
  • Nothing against Mat Ryer, as his pattern is the best I've found, but I still feel like there's some better solution out there.

    • ให้ความเคารพต่อแพตเทิร์นของ Mat Ryer: ไม่ได้มีอะไรติดใจ Mat Ryer เพราะแพตเทิร์นของเขาดีที่สุดเท่าที่เคยเจอ แต่ก็ยังรู้สึกว่าน่าจะมีวิธีที่ดีกว่านี้อยู่
  • one of my biggest pet peeves is when people take a Config object, which represents the configuration of an entire system, and pass it around mutably.

    • ความไม่พอใจต่อการใช้ Config object: สิ่งที่ขัดใจมากอย่างหนึ่งคือการนำ Config object ซึ่งแทนค่าการตั้งค่าของทั้งระบบ ไปส่งต่อแบบที่แก้ไขเปลี่ยนแปลงได้
  • When you do that, you're coupling everything together through the config object.

    • ปัญหาการผูกกันผ่าน Config object: การทำเช่นนั้นทำให้ทุกอย่างถูกผูกติดกันผ่าน Config object
  • I've worked on systems where you had to configure the parts in a specific order in order for things to work, because someone decided to write back to the config object when it was passed to them.

    • ปัญหาการพึ่งพาลำดับกับ Config object: เคยทำงานกับระบบที่ต้องตั้งค่าส่วนประกอบตามลำดับเฉพาะจึงจะทำงานได้ เพราะมีคนตัดสินใจเขียนค่ากลับเข้าไปใน Config object ที่ถูกส่งต่อมา
  • Or another case was where I've seen it such that you couldn't disable a portion of the system because it wrote data into the config object that was read by some other subsystem later.

    • ปัญหาการปิดบางส่วนของระบบ: อีกกรณีหนึ่งคือเคยเห็นว่าไม่สามารถปิดการทำงานบางส่วนของระบบได้ เพราะส่วนนั้นเขียนข้อมูลลงใน Config object แล้วภายหลังมี subsystem อื่นมาอ่านข้อมูลนั้นต่อ
  • The pattern of "your configuration is one big value, which is mutable" is one of the more annoying patterns that I've seen before, both in Go and in other languages.

    • วิจารณ์แพตเทิร์นการตั้งค่าขนาดใหญ่ที่แก้ไขได้: มองว่าแพตเทิร์นแบบ "ค่าการตั้งค่าของคุณเป็นก้อนใหญ่ก้อนเดียวและแก้ไขเปลี่ยนแปลงได้" เป็นหนึ่งในแพตเทิร์นที่น่ารำคาญที่สุดที่เคยเจอ ทั้งใน Go และภาษาอื่น ๆ
  • I agree with a lot of this, I'll add my own opinions:

    • เห็นด้วยและขอเสริมความเห็น: เห็นด้วยกับหลายส่วน และขอเพิ่มความเห็นของตัวเอง
  • I would pass a waitgroup with the app context to service structs.

    • เสนอให้ส่ง waitgroup กับ app context: เสนอให้ส่ง waitgroup พร้อมกับ app context เข้าไปยัง service struct
  • This way the interrupt can trigger the app shutdown via the context and the main goroutine can wait on the waitgroup before actually killing the app.

    • ใช้ interrupt และ waitgroup เพื่อปิดแอป: วิธีนี้ทำให้ interrupt สามารถกระตุ้นการปิดแอปผ่าน context ได้ และ main goroutine ก็สามารถรอบน waitgroup ก่อนปิดแอปจริง
  • If writing a CLI program, then testing stdout, stdin, stderr, args, env, etc. is useful.

    • ประโยชน์ของการทดสอบ CLI: หากกำลังเขียนโปรแกรม CLI การทดสอบ stdout, stdin, stderr, args, env และอื่น ๆ มีประโยชน์มาก
  • But for an http server, this is less true.

    • แนวทางที่ต่างออกไปสำหรับ HTTP server: แต่สำหรับ HTTP server สิ่งเหล่านี้มีความสำคัญน้อยกว่า
  • I would pass structured config to the run function to let those tests be more focused.

    • ส่ง config แบบมีโครงสร้างเพื่อให้ทดสอบได้ตรงจุด: เสนอให้ส่ง config ที่มีโครงสร้างเข้าไปยังฟังก์ชัน run เพื่อให้การทดสอบโฟกัสได้มากขึ้น
  • I disagree with parsing templates using sync.Once in a handler because I don't think handlers should do template parsing at all.

    • ไม่เห็นด้วยกับการ parse template ใน handler: ไม่เห็นด้วยกับการ parse template ด้วย sync.Once ภายใน handler เพราะมองว่า handler ไม่ควรทำการ parse template ตั้งแต่แรก
  • I would do this when the app starts: if the template cannot be parsed, the app should not become ready to receive any requests and should rather exit with a non-zero exit code.

    • เสนอให้ parse template ตอนเริ่มแอป: ควรทำการ parse template ตอนแอปเริ่มต้น และหาก parse ไม่ได้ แอปก็ไม่ควรพร้อมรับ request ใด ๆ แต่ควรจบการทำงานด้วย exit code ที่ไม่ใช่ศูนย์
  • I found fx to be a super simple yet versatile tool to design my application around.

    • fx เรียบง่ายแต่ยืดหยุ่นมาก: มองว่า fx เป็นเครื่องมือที่เรียบง่ายมากแต่ก็ยืดหยุ่นสูงสำหรับใช้เป็นแกนในการออกแบบแอปพลิเคชัน
  • All the advice in the article is still helpful, but it takes the "how do I make sure X is initialized when Y needs it" part completely out of the equation and reduces it from an N*M problem to an N problem.

    • คำแนะนำในบทความยังมีประโยชน์และข้อดีของ fx: คำแนะนำทั้งหมดในบทความยังคงมีประโยชน์ แต่ fx ช่วยตัดปัญหาเรื่อง "จะทำอย่างไรให้มั่นใจว่า X ถูก initialize แล้วเมื่อ Y ต้องใช้มัน" ออกไปจากสมการโดยสิ้นเชิง และลดปัญหาจาก N*M ให้เหลือแค่ N
  • I've used quite a few dependency injection libraries in various languages over the years (and implemented a couple myself) and the simplicity and versatility of fx makes it my favorite so far.

    • ความชื่นชอบต่อ fx: ตลอดหลายปีที่ผ่านมาเคยใช้ไลบรารี dependency injection มาหลายตัวในหลายภาษา และยังเคยลงมือทำเองอยู่สองสามตัว แต่ความเรียบง่ายและความยืดหยุ่นของ fx ทำให้มันเป็นตัวโปรดที่สุดจนถึงตอนนี้
  • I've recently been playing with ogen:

    • ประสบการณ์กับ ogen: ช่วงหลังมานี้ได้ลองเล่นกับ ogen
  • Write openapi definition, it'll do routing, definition of structs, validation of JSON schemas, etc.

    • การเขียน openapi definition และความสามารถของ ogen: เพียงเขียน openapi definition แล้ว ogen จะจัดการ routing, การนิยาม struct, การตรวจสอบความถูกต้องของ JSON schema และอื่น ๆ ให้
  • All I need to do is implement the service.

    • ทำให้การพัฒนา service ง่ายขึ้น: สิ่งที่ต้องทำมีแค่ implement service เท่านั้น
  • Validating an integer range for a querystring parameter is just too boring. And too easy to mistype when writing it manually.

    • ข้อเสียของการตรวจช่วงค่าจำนวนเต็มใน querystring: การตรวจสอบช่วงค่าจำนวนเต็มสำหรับพารามิเตอร์ใน querystring นั้นน่าเบื่อเกินไป และยังพิมพ์ผิดได้ง่ายเมื่อเขียนด้วยมือ
  • Anyways, so far only been playing, so haven't found the bad parts yet.

    • ความเห็นเบื้องต้นต่อ ogen: อย่างไรก็ตาม ตอนนี้ยังแค่ลองเล่นอยู่ จึงยังไม่เจอส่วนที่แย่
  • Great article with lots of interesting ideas. Can't believe I didn't know about signal.NotifyContext. Finally I'll be able to actually rememeber how to respond to signals instead of copy-pasting that between projects.

    • ชื่นชมบทความและ signal.NotifyContext: มองว่าเป็นบทความที่ยอดเยี่ยมและมีไอเดียที่น่าสนใจมากมาย แถมยังไม่อยากเชื่อว่าตัวเองไม่เคยรู้จัก signal.NotifyContext มาก่อน สุดท้ายก็จะจำวิธีตอบสนองต่อ signal ได้จริง ๆ แทนที่จะคัดลอกวางข้ามโปรเจ็กต์ไปมา
  • I like a lot of what they've done here. My testing looks a bit different however.

    • ชอบแนวทางในบทความแต่มีวิธีทดสอบต่างออกไป: ชอบหลายอย่างที่บทความนี้ทำ แต่แนวทางการทดสอบของตัวเองต่างออกไปเล็กน้อย
  • srv, err := newTestServer()

    • ตัวอย่างโค้ดสร้าง test server: ยกตัวอย่างโค้ดสำหรับสร้าง test server ใหม่
  • require.NoError(t, err)

    • ตัวอย่างโค้ดตรวจสอบ error: ยกตัวอย่างโค้ดสำหรับตรวจว่าไม่มี error
  • defer srv.Close()

    • ตัวอย่างโค้ดปิด server: ยกตัวอย่างโค้ดสำหรับปิด server หลังทดสอบเสร็จ
  • resp, err := http.Post(fmt.Sprintf("http://localhost:%d/signup/json";, srv.Port()), "application/json", strings.NewReader({ "email": "test@example.com", "password": "p@55Word", "password_copy": "p@55Word" }))

    • ตัวอย่างโค้ดส่ง HTTP POST request: ยกตัวอย่างโค้ดสำหรับส่ง HTTP POST request
  • In my newTestServer, I spin up a server with fakes for my dependencies.

    • สร้าง server จำลองสำหรับ dependency: ใน newTestServer จะสตาร์ต server พร้อม fake สำหรับ dependency ต่าง ๆ
  • If I want to test a dependency error, I replace that property with a fake that will return an error.

    • วิธีทดสอบ error ของ dependency: หากต้องการทดสอบ error จาก dependency ก็จะเปลี่ยนพร็อพเพอร์ตีนั้นให้เป็น fake ที่คืนค่า error
  • I can validate my error paths. I can validate my log entries. I can validate my metric emission. I can validate timeouts and graceful shutdowns.

    • สิ่งที่ตรวจสอบได้หลากหลาย: สามารถตรวจสอบเส้นทาง error, รายการ log, การส่ง metric, timeout และ graceful shutdown ได้
  • After the server starts, I inspect to determine which port it is running on (default is :0 so I have to wait to see what it got bound to).

    • ตรวจพอร์ตหลัง server เริ่มทำงาน: หลังจาก server เริ่มทำงานแล้ว จะตรวจดูว่ามันรันอยู่บนพอร์ตใด (ค่าเริ่มต้นคือ :0 จึงต้องรอเพื่อดูว่ามันถูก bind ไปที่พอร์ตไหน)
  • My "unit" tests can test at the handler level or the http level, making sure that I can fully test the code as the users of my system will see it, exercising all middleware or none.

    • ขอบเขตของ "unit" test: "unit" test ของตนสามารถทดสอบได้ทั้งระดับ handler หรือระดับ HTTP ทำให้มั่นใจได้ว่าสามารถทดสอบโค้ดได้ครบถ้วนในแบบที่ผู้ใช้ระบบจะได้เห็นจริง ไม่ว่าจะผ่าน middleware ทั้งหมดหรือไม่ผ่านเลยก็ตาม
  • I can spin up N instances and run my tests in parallel.

    • รันการทดสอบแบบขนานได้: สามารถสตาร์ตอินสแตนซ์ได้ N ตัวและรันการทดสอบแบบขนาน
  • I don't write go, but I like these patterns. Feels fairly universal for testable code.

    • แม้ไม่ได้เขียน Go แต่ชอบแพตเทิร์นเหล่านี้: แม้จะไม่ได้เขียน Go แต่ก็ชอบแพตเทิร์นเหล่านี้ และรู้สึกว่าเป็นแนวคิดที่ค่อนข้างใช้ได้ทั่วไปสำหรับโค้ดที่ทดสอบได้