1 điểm bởi GN⁺ 2025-04-13 | 1 bình luận | Chia sẻ qua WhatsApp

Bối cảnh

  • Erlang là ngôn ngữ được phát triển để xây dựng các hệ thống phân tán đáng tin cậy, ban đầu khởi đầu như một thư viện Prolog rồi phát triển thành một ngôn ngữ độc lập.
  • Nó được dùng tại Ericsson để lập trình tổng đài điện thoại, và đến năm 1998 thì được chuyển sang mã nguồn mở.
  • Joe Armstrong là một trong những nhà thiết kế chính của Erlang, và luận án tiến sĩ của ông nói về cách tạo ra các hệ thống phân tán đáng tin cậy trong tình trạng phần mềm có lỗi.

Hành vi (Behaviours)

  • Hành vi trong Erlang tương tự interface trong Java hay Go, là tập hợp các chữ ký kiểu có thể có nhiều cách hiện thực.
  • Với hành vi, bạn chỉ cần viết phần mã định nghĩa logic nghiệp vụ của chương trình, còn mã hạ tầng sẽ được cung cấp tự động.
  • Hành vi được các chuyên gia viết ra và dựa trên các thực tiễn tốt nhất.

Hành vi máy chủ tổng quát

  • gen_server được giải thích bằng ví dụ hiện thực một kho lưu trữ key-value.
  • handle_call có vai trò cập nhật trạng thái hoặc tra cứu khóa, và toàn bộ tính đồng thời đều được ẩn trong thành phần gen_server.

Hành vi trình quản lý sự kiện

  • gen_event là một trình quản lý sự kiện, đăng ký các event handler và thực thi chúng khi thông điệp đến.
  • Nó hữu ích cho ghi log lỗi, và có đưa ra một ví dụ logger đơn giản.

Hành vi máy trạng thái

  • gen_fsm đã được đổi tên thành gen_statem, và phù hợp để hiện thực giao thức.

Hành vi giám sát

  • Supervisor đảm bảo các tiến trình khác hoạt động bình thường và sẽ khởi động lại theo chiến lược định sẵn khi có lỗi.
  • Chiến lược one_for_one chỉ khởi động lại tiến trình bị lỗi, còn chiến lược one_for_all sẽ khởi động lại mọi tiến trình con nếu một tiến trình gặp lỗi.

Hành vi ứng dụng và phát hành

  • Application bao gồm cây supervisor và mọi thứ cần thiết, còn release sẽ đóng gói một hoặc nhiều application.
  • Khi nâng cấp thất bại thì phải có khả năng rollback.

Cách hiện thực hành vi

  • Chính cấu trúc của các hành vi, hơn là tiến trình nhẹ và truyền thông điệp của Erlang, mới dẫn tới phần mềm đáng tin cậy.
  • Để hiện thực hành vi trong các ngôn ngữ khác, có thể bắt đầu bằng cách dùng chữ ký interface.

Tính đúng đắn của hành vi

  • Kiểm thử mô phỏng giúp việc kiểm thử hệ thống phân tán dễ dàng hơn, và có thể dùng cấu trúc của hành vi gen_server để đơn giản hóa việc xử lý vấn đề.

Đóng góp

  • Có những ý tưởng như vay mượn từ công trình của Martin Thompson để tạo event loop nhanh, thêm I/O bất đồng bộ, v.v.
  • Nếu quan tâm hoặc có ý kiến, đề xuất hay câu hỏi, bạn có thể liên hệ.

1 bình luận

 
GN⁺ 2025-04-13
Ý kiến trên Hacker News
  • Điều đáng kinh ngạc ở Erlang và BEAM là chiều sâu trong các tính năng của chúng. Với OP, thu hoạch lớn nhất là Behavior/Interface của Erlang. Cá nhân tôi cho rằng điểm quan trọng là lượng nguồn lực phát triển cần thiết để xây dựng các hệ thống phức tạp ít hơn rất nhiều so với các ngôn ngữ khác. Với nhiều người, các tiến trình nhẹ và mô hình lập trình là điểm hấp dẫn

    • OTP bao gồm cực kỳ nhiều tính năng. Chúng tôi đang thực hiện việc biên dịch để có thể chạy Elixir trên thiết bị iOS. Có thể dùng thư viện ei của Erlang để biên dịch node từ C và giao tiếp với các node Erlang khác. Thông qua thư viện rpc của Erlang, có thể gọi hàm từ C và giao tiếp với ứng dụng Elixir
    • Erlang đã giải quyết nhiều vấn đề mà các stack công nghệ hiện đại đang vật lộn, và đã xử lý bài toán khả năng mở rộng cùng chi phí triển khai từ vài chục năm trước. Tuy nhiên trên HN, sự quan tâm tới Erlang/Elixir không dẫn tới việc áp dụng thực tế, và nhiều công ty đang lãng phí tiền bạc để tự triển khai những thứ vốn được cung cấp miễn phí trong stack Erlang
  • Tôi từng làm việc với vài nhà quản lý và những người muốn viết sách dựa trên kinh nghiệm của mình. Chúng tôi luôn bất đồng về các yếu tố dẫn đến thành công. Một số người cho rằng tiến trình nhẹ và truyền thông điệp không phải là bí quyết cốt lõi, nhưng họ bỏ qua việc Communicating Sequential Processes của Erlang không thể tách rời khỏi các đặc tính này

    • Ví dụ: lập trình viên ứng dụng viết mã tuần tự, còn mọi tính đồng thời đều được ẩn trong các behavior
    • Thành viên mới rất dễ bắt đầu: logic nghiệp vụ là tuần tự và có cấu trúc tương tự những gì họ có thể đã từng thấy trước đó
    • Supervisor và triết lý "let it crash" góp phần tạo ra những hệ thống đáng tin cậy
  • Tôi bắt đầu quan tâm trở lại tới Erlang vì các tiến trình nhẹ và truyền thông điệp. Cho tới hiện tại, behavior vẫn là thứ yếu

    • Dự án là đưa Flow Based Programming (FBP) trực quan vào Erlang. FBP có vẻ rất hợp với Erlang, và tôi ngạc nhiên vì nó đã tồn tại sẵn
    • Tôi đang dùng Node-RED như công cụ cho FBP, và ý tưởng cơ bản là kết nối frontend Node-RED với backend Erlang rồi biến mọi node thành một tiến trình
  • Tôi đã tìm thông tin về lý do Ericsson ngừng dùng Erlang và việc Joe bị sa thải

    • Câu trả lời ngắn gọn là Erlang bị gạt ra ngoài khi họ chuyển sang Java cho các dự án mới. Joe và các đồng nghiệp đã thành lập Bluetail vào năm 1998 và được Nortel mua lại. Nortel là một gã khổng lồ viễn thông; giá cổ phiếu của hãng đạt $125 vào năm 2000 nhưng đến năm 2002 đã rơi xuống dưới $1. Điều này liên quan đến sự sụp đổ của bong bóng dot-com và việc chi tiêu cho viễn thông suy giảm
  • Sức mạnh của Erlang/Elixir không nằm ở việc hiện thực mô hình Actor, matching của Prolog, tính bất biến hay behavior, mà nằm ở khát vọng của Joe muốn chứng minh rằng có thể làm được nhiều hơn với ít tài nguyên hơn

    • Đây là một hệ thống được thiết kế tốt và nhất quán, với mức độ nhất quán hiếm thấy ở các ngôn ngữ khác. Nó không hoàn hảo nhưng rất ấn tượng
    • Tôi nghĩ thế giới phần mềm vẫn còn thiếu sự nhận thức và chấp nhận đối với sức mạnh mà sự đơn giản mang lại
  • Erlang, OTP, BEAM cung cấp nhiều hơn là behavior. VM giống như một nhân ảo, cung cấp supervisor, các tiến trình cô lập và chế độ phân tán. OTP còn cung cấp các mô-đun hữu ích như Mnesia (cơ sở dữ liệu), bộ đếm nguyên tử/bảng ETS (caching), v.v.

    • Một năm trước, tôi đã áp dụng Erlang làm ngôn ngữ backend tại công ty tư vấn cá nhân của mình. Tôi đã khám phá bên trong BEAM để thay thế stack dựa trên TCP bằng QUIC và tích hợp các bản vá Rust
  • Khái niệm thú vị nhất trong Erlang/BEAM là khả năng phục hồi từng phần được tích hợp sẵn như mặc định. Khi xảy ra trạng thái ngoài dự kiến, thay vì kết thúc toàn bộ tiến trình hoặc chấp nhận rủi ro gây hỏng hóc, hệ thống sẽ rollback về trạng thái tốt đã biết ở mức chi tiết nhất có thể

  • Lý do các nhà thiết kế ngôn ngữ và thư viện khác không sao chép cấu trúc behavior của Erlang là vì chữ ký hàm behavior của Erlang gắn chặt với những tính năng khác của Erlang, đặc biệt là cách sử dụng tính bất biến rất riêng của nó

    • Để đạt cùng mục tiêu ở ngôn ngữ khác, không nên sao chép trực tiếp cách làm của Erlang. Tôi khuyến khích học hỏi từ phần mềm đáng tin cậy của Erlang, nhưng phản đối mạnh việc bê nguyên cách làm của Erlang sang các ngôn ngữ khác
  • Tôi không đồng ý với nội dung bài viết này. Behavior có thể tồn tại nhờ kiến trúc nền tảng của hệ thống. Behavior không phải interface mà giống với abstract object trong các ngôn ngữ như Java hơn

    • Bài báo của Joe cho thấy cách xây dựng các hệ thống đáng tin cậy bằng cách sử dụng một bộ khối Lego cho trước
  • Behavior không quá thú vị. Nó cũng tồn tại ở các ngôn ngữ lập trình khác. Điều thú vị ở BEAM là việc ném lỗi cực kỳ thanh lịch. Việc ném lỗi và sức mạnh của behavior giúp dễ dàng bắt lỗi, báo cáo thông tin ngữ cảnh và nhìn chung khiến mọi thứ có thể kết hợp tốt với nhau