2 điểm bởi GN⁺ 2024-02-10 | 1 bình luận | Chia sẻ qua WhatsApp

GrafanaCON 2024: Đăng ký ngay hôm nay và giữ chỗ của bạn!

  • GrafanaCON 2024 là sự kiện cộng đồng lớn nhất năm nay, và việc đăng ký đã chính thức bắt đầu.
  • Sự kiện này mang đến trải nghiệm trực tiếp đầy sống động tại Amsterdam vào tháng 4.

Ý kiến của GN⁺

  • GrafanaCON 2024 là một sự kiện quan trọng đối với những ai quan tâm đến trực quan hóa dữ liệu và giám sát. Đây sẽ là nơi cộng đồng người dùng và nhà phát triển Grafana cùng tụ họp để chia sẻ các xu hướng và công nghệ mới nhất.
  • Sự kiện lần này được tổ chức tại Amsterdam dự kiến sẽ mang đến cho người tham dự cơ hội kết nối và học hỏi, cùng các phiên thảo luận giúp hiểu sâu hơn về các công cụ phân tích và trực quan hóa dữ liệu.
  • Việc mở đăng ký là tin vui đối với người dùng Grafana, và sẽ là cơ hội tốt để các chuyên gia trong lĩnh vực này tiếp thu kiến thức mới và giao lưu với các đồng nghiệp trong ngành.

1 bình luận

 
GN⁺ 2024-02-10
Ý kiến trên 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.

    • Cách kiểm tra tính hợp lệ: Nhận vào một context tùy chọn và trả về một map, trong đó các trường có vấn đề được dùng làm key và phần mô tả lỗi dễ hiểu cho con người được dùng làm value. Tác giả cho biết cách này đã từng hữu ích với mình.
  • 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.

    • Phân tích thay vì kiểm tra hợp lệ: Sau khi đọc "Parse, Don't Validate" của Lexi Lambda, người viết cảm thấy việc tận dụng trình kiểm tra kiểu tích hợp của Go ít dễ gây lỗi hơn so với dùng validator.
  • 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.

    • Ví dụ về kiểm tra username: Hãy tưởng tượng bạn muốn ngăn người dùng chọn một username không hợp lệ, chẳng hạn đảm bảo họ không thể dùng username chứa dấu ngoặc nhọn <>.
  • 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.

    • Vấn đề của cách tiếp cận validator: Bạn phải nhớ gọi validator ở 100% các nhánh mã nơi giá trị username đến từ nguồn không đáng tin cậy.
  • Instead of using a validator, you can do this:

    • Đề xuất phương án thay thế validator: Thay vì dùng validator, tác giả đề xuất một cách khác.
  • 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.

    • Đảm bảo hợp lệ qua quá trình tạo đối tượng: Cách này đảm bảo bạn không thể quên kiểm tra username ở bất kỳ nhánh mã nào. Nếu đã có một đối tượng Username, thì chắc chắn nó đã được kiểm tra vì không có cách nào khác để tạo ra nó.
  • 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.

    • Đánh giá cao công việc của Mat Ryer: Người viết rất thích công việc của Mat Ryer và đã áp dụng hầu hết các ý tưởng từ phiên bản 2018 của bài viết này vào mọi dự án Go của mình kể từ đó.
  • The one weak spot for me is this aspect:

    • Chỉ ra điểm yếu: Có một khía cạnh mà người viết thấy là điểm yếu.
  • This has always felt wrong to me, but I've never been able to figure out a better solution.

    • Chưa tìm ra giải pháp tốt hơn: Người viết luôn cảm thấy điều này không ổn, nhưng chưa bao giờ tìm ra được cách giải quyết tốt hơn.
  • It means that a huge chunk of your code has a huge amount of unnecessary shared state.

    • Vấn đề của shared state: Điều đó khiến một phần rất lớn trong mã của bạn phải mang theo quá nhiều trạng thái dùng chung không cần thiết.
  • I often end up writing HTTP handlers that only need access to a tiny amount of the shared state.

    • HTTP handler và shared state: Nhiều khi người viết tạo các HTTP handler chỉ cần truy cập vào một phần rất nhỏ của 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.

    • Tôn trọng pattern của Mat Ryer: Không có ý chê Mat Ryer, vì đây là pattern tốt nhất mà người viết từng thấy, nhưng họ vẫn cảm giác đâu đó còn có giải pháp tốt hơn.
  • 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.

    • Khó chịu với cách dùng đối tượng Config: Một trong những điều khiến người viết khó chịu nhất là khi mọi người lấy một đối tượng Config đại diện cho cấu hình của cả hệ thống rồi chuyền nó đi dưới dạng có thể thay đổi được.
  • When you do that, you're coupling everything together through the config object.

    • Vấn đề coupling qua Config: Làm như vậy sẽ khiến mọi thứ bị ràng buộc với nhau thông qua đối tượng config.
  • 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.

    • Phụ thuộc thứ tự do Config: Người viết từng làm trên các hệ thống mà các thành phần phải được cấu hình theo một thứ tự nhất định thì mới chạy được, vì có ai đó đã ghi ngược dữ liệu trở lại vào đối tượng config khi nó được truyền vào.
  • 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.

    • Không thể vô hiệu hóa một phần hệ thống vì Config: Cũng có trường hợp người viết thấy không thể tắt một phần của hệ thống, vì phần đó ghi dữ liệu vào đối tượng config và sau này một subsystem khác lại đọc dữ liệu đó.
  • 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.

    • Phê phán pattern cấu hình lớn có thể thay đổi: Pattern kiểu “cấu hình của bạn là một giá trị lớn duy nhất và có thể thay đổi” là một trong những pattern gây khó chịu hơn cả mà người viết từng thấy, cả trong Go lẫn các ngôn ngữ khác.
  • I agree with a lot of this, I'll add my own opinions:

    • Đồng ý và bổ sung ý kiến riêng: Người viết đồng ý với nhiều điểm trong đó và muốn thêm quan điểm của riêng mình.
  • I would pass a waitgroup with the app context to service structs.

    • Đề xuất truyền waitgroup cùng app context: Người viết sẽ truyền một waitgroup cùng với app context vào các 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.

    • Dùng interrupt và waitgroup để tắt ứng dụng: Làm như vậy, interrupt có thể kích hoạt quá trình shutdown của ứng dụng thông qua context, còn goroutine chính có thể chờ waitgroup trước khi thực sự dừng ứng dụng.
  • If writing a CLI program, then testing stdout, stdin, stderr, args, env, etc. is useful.

    • Tính hữu ích của kiểm thử CLI: Nếu viết chương trình CLI, việc kiểm thử stdout, stdin, stderr, args, env... là rất hữu ích.
  • But for an http server, this is less true.

    • Khác biệt với HTTP server: Nhưng với một HTTP server thì điều đó ít đúng hơn.
  • I would pass structured config to the run function to let those tests be more focused.

    • Truyền cấu hình có cấu trúc để kiểm thử tập trung hơn: Người viết sẽ truyền một cấu hình có cấu trúc vào hàm run để các bài kiểm thử tập trung hơn.
  • I disagree with parsing templates using sync.Once in a handler because I don't think handlers should do template parsing at all.

    • Phản đối việc parse template trong handler: Người viết không đồng ý với việc parse template bằng sync.Once trong handler, vì họ cho rằng handler hoàn toàn không nên làm việc 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.

    • Đề xuất parse template khi ứng dụng khởi động: Người viết sẽ làm việc này ngay khi ứng dụng khởi động: nếu template không parse được, ứng dụng không nên ở trạng thái sẵn sàng nhận request mà nên thoát với mã lỗi khác 0.
  • I found fx to be a super simple yet versatile tool to design my application around.

    • fx đơn giản nhưng đa dụng: Người viết thấy fx là một công cụ cực kỳ đơn giản nhưng linh hoạt để thiết kế ứng dụng của mình.
  • 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.

    • Lợi ích của fx so với lời khuyên trong bài: Mọi lời khuyên trong bài vẫn hữu ích, nhưng fx loại bỏ hoàn toàn câu hỏi “làm sao đảm bảo X đã được khởi tạo khi Y cần đến nó”, biến bài toán từ N*M thành chỉ còn 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 là lựa chọn ưa thích: Trong nhiều năm, người viết đã dùng không ít thư viện dependency injection ở nhiều ngôn ngữ khác nhau, thậm chí tự triển khai vài cái, nhưng sự đơn giản và linh hoạt của fx khiến nó trở thành lựa chọn họ thích nhất cho đến nay.
  • I've recently been playing with ogen:

    • Trải nghiệm với ogen: Gần đây người viết đang thử dùng ogen.
  • Write openapi definition, it'll do routing, definition of structs, validation of JSON schemas, etc.

    • Chức năng của ogen với OpenAPI: Chỉ cần viết định nghĩa OpenAPI, ogen sẽ lo phần routing, định nghĩa struct, kiểm tra hợp lệ của JSON schema, v.v.
  • All I need to do is implement the service.

    • Đơn giản hóa việc triển khai service: Tất cả những gì người viết cần làm là triển khai service.
  • Validating an integer range for a querystring parameter is just too boring. And too easy to mistype when writing it manually.

    • Nhược điểm của việc tự viết kiểm tra dải số nguyên cho query string: Việc kiểm tra dải giá trị số nguyên cho tham số query string quá nhàm chán, và cũng rất dễ gõ sai khi tự viết thủ công.
  • Anyways, so far only been playing, so haven't found the bad parts yet.

    • Đánh giá ban đầu về ogen: Dù sao thì đến giờ người viết mới chỉ thử nghiệm, nên vẫn chưa thấy điểm dở nào.
  • 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.

    • Đánh giá tích cực về bài viết và signal.NotifyContext: Đây là một bài viết hay với nhiều ý tưởng thú vị. Người viết không thể tin là trước giờ mình lại không biết signal.NotifyContext. Cuối cùng thì họ cũng có thể thật sự nhớ cách phản hồi với signal thay vì cứ copy-paste giữa các dự án.
  • I like a lot of what they've done here. My testing looks a bit different however.

    • Thích cách tiếp cận nhưng khác ở phần kiểm thử: Người viết thích nhiều điều mà bài viết đã làm, nhưng cách kiểm thử của họ thì hơi khác.
  • srv, err := newTestServer()

    • Ví dụ mã tạo test server: Đưa ra ví dụ mã để tạo một test server mới.
  • require.NoError(t, err)

    • Ví dụ mã kiểm tra lỗi: Đưa ra ví dụ mã kiểm tra không có lỗi.
  • defer srv.Close()

    • Ví dụ mã đóng server: Đưa ra ví dụ mã đóng server sau khi kiểm thử xong.
  • 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" }))

    • Ví dụ mã gửi HTTP POST: Đưa ra ví dụ mã gửi một yêu cầu HTTP POST.
  • In my newTestServer, I spin up a server with fakes for my dependencies.

    • Dùng thành phần giả cho dependency trong test server: Trong newTestServer, người viết khởi tạo một server với các dependency giả.
  • If I want to test a dependency error, I replace that property with a fake that will return an error.

    • Cách kiểm thử lỗi dependency: Nếu muốn kiểm thử lỗi từ dependency, người viết thay thuộc tính đó bằng một bản giả sẽ trả về lỗi.
  • 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.

    • Nhiều khía cạnh có thể kiểm chứng: Người viết có thể kiểm chứng các nhánh lỗi, các mục log, việc phát metric, timeout và cả 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).

    • Kiểm tra cổng sau khi server khởi động: Sau khi server khởi động, người viết kiểm tra để xác định nó đang chạy trên cổng nào (mặc định là :0 nên phải chờ xem nó được bind vào cổng nào).
  • 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.

    • Phạm vi của “unit” test: Các bài “unit” test của người viết có thể kiểm thử ở cấp độ handler hoặc cấp độ HTTP, bảo đảm có thể kiểm thử đầy đủ mã nguồn theo đúng cách người dùng hệ thống sẽ nhìn thấy, với toàn bộ middleware hoặc không dùng middleware nào.
  • I can spin up N instances and run my tests in parallel.

    • Chạy kiểm thử song song: Người viết có thể khởi tạo N instance và chạy các bài kiểm thử song song.
  • I don't write go, but I like these patterns. Feels fairly universal for testable code.

    • Không viết Go nhưng thích các pattern này: Người viết không viết Go, nhưng họ thích các pattern này vì chúng có vẻ khá phổ quát cho mã dễ kiểm thử.