- Thay vì gọi trực tiếp API thanh toán khắp logic sản phẩm, exe ghi nhận các thay đổi trạng thái thành sự kiện có thể tính phí (billable facts) và đối soát trạng thái đã được xác định với Stripe
- Trong cấu trúc cũ, transaction cơ sở dữ liệu và lệnh gọi API thanh toán đan xen, khiến các ngoại lệ như thất bại một phần, trạng thái thuê bao bất thường, hay thanh toán bị từ chối làm rung chuyển cả luồng sản phẩm
- Khi thêm ghế cho nhóm, hệ thống đánh dấu trạng thái là dirty, rồi worker phía sau tính toán số lượng theo quy tắc nghiệp vụ và chỉ cập nhật số lượng thuê bao trên Stripe khi thực sự có thay đổi
- Khi tách thanh toán ra, onboarding thành viên mới của nhóm không còn phụ thuộc vào mã thanh toán, và ngay cả khi thay đổi quy tắc tính ghế cũng không ảnh hưởng đến luồng mời và tham gia
- Cùng cấu trúc đối soát đó cũng được áp dụng cho tính phí theo mức sử dụng như VM đang hoạt động và dung lượng đĩa, cũng như mua hàng trong ứng dụng trên iOS, để vẫn giữ nguyên các sự kiện sản phẩm và chỉ thay phần tích hợp theo từng nhà cung cấp thanh toán
Tách logic thanh toán khỏi luồng sản phẩm
- Khi logic thanh toán trộn lẫn với logic nghiệp vụ thông thường, mã liên quan sẽ lan ra mọi đường đi cốt lõi cần tính phí, đồng thời cấu trúc giá cũng trở nên mong manh và khó thay đổi
- exe hướng tới cách làm mà không để một người độc quyền kiến thức thanh toán, để ai cũng có thể sửa mã liên quan, trong khi các ngoại lệ phức tạp sẽ do người phụ trách chuyên môn xử lý
- Ban đầu, việc tính phí ghế nhóm được gói vào một luồng lớn duy nhất từ lúc chấp nhận lời mời đến khi thanh toán
- Người dùng chấp nhận lời mời, xác nhận tài khoản rồi tham gia nhóm
- Họ được cấp quyền truy cập VM dùng chung và tài nguyên tính toán theo gói cước
- Trong quá trình này còn gọi cả API thanh toán
- Khi ghép thay đổi cơ sở dữ liệu với lệnh gọi API bên ngoài như vậy, có thể xảy ra thất bại một phần khi chỉ một phía thành công
- Trạng thái thuê bao của nhóm có thể trở nên bất thường
- Thanh toán cho ghế bổ sung có thể bị từ chối
- Càng nhiều ngoại lệ tích tụ, toàn bộ cấu trúc càng trở nên mong manh
Sự kiện có thể tính phí và đối soát hậu kỳ
- Sự kiện có thể tính phí là thao tác mang tính nguyên tử cho biết một trạng thái cụ thể đã thay đổi
- Trước tiên thực thi logic sản phẩm để xác định trạng thái mới của tài nguyên
- Sau đó dựa trên sự kiện đã xác định để đối soát trạng thái của nhà cung cấp thanh toán
- Stripe không cần biết quá trình đã đi đến trạng thái đó ra sao mà chỉ cần số lượng cuối cùng
-
Đối soát ghế nhóm
- Khi lời mời được chấp nhận, trạng thái ghế của nhóm được đánh dấu là dirty
- Worker phía sau phát hiện trạng thái dirty và tính toán phần tăng giảm số ghế theo quy tắc nghiệp vụ
- Chỉ khi số lượng khác đi thì mới cập nhật số lượng thuê bao trên Stripe
- Vì việc thêm thành viên nhóm và mã thanh toán đã được tách rời, nên ngay cả khi viết lại luồng mời thì phần tính phí cũng không bị hỏng theo, và cách tính ghế cũng có thể thay đổi độc lập
-
Tính phí theo mức sử dụng và mua hàng trong ứng dụng
- Cùng quy trình đối soát đó được áp dụng cho mọi tính phí theo mức sử dụng
- Hệ thống ghi nhận các sự kiện về VM đang hoạt động và mức sử dụng đĩa
- Worker đo đếm sẽ đối soát chúng với trạng thái của nhà cung cấp thanh toán
- Dù thêm phương thức tính phí mới, các sự kiện vẫn giữ nguyên, chỉ khác cách đối soát với từng API
- Ứng dụng iOS cũng chỉ truyền đi sự kiện rằng ai đó đã đăng ký qua mua hàng trong ứng dụng, còn trạng thái thanh toán thực tế sẽ được đối soát về sau
- Cấu trúc thanh toán đã trở thành khu vực mà các thành viên không chuyên về thanh toán cũng có thể xử lý, đồng thời khả năng những thay đổi tính năng sản phẩm như luồng mời làm hỏng hệ thống tính phí cũng giảm đi
- Cùng quy trình đối soát đó được áp dụng cho mọi tính phí theo mức sử dụng
1 bình luận
Các ý kiến trên Lobste.rs
Trọng tâm của bài viết, cách phát hiện và xử lý bất đồng bộ các phần thay đổi, rất phù hợp để giảm độ phụ thuộc và triển khai các tác dụng phụ.
Tuy nhiên, LLM là công cụ có xu hướng tăng tốc hiện tượng mã bị rải rác khắp nơi hơn là ngăn chặn nó, nên dễ trở thành nợ kiến trúc. Cũng đáng nghi ngờ là làm sao có thể rà soát lượng mã được tạo ra nhanh hơn tốc độ con người hiểu được; đoạn nói rằng Exe thậm chí không review mã còn đáng sợ hơn.
Kiến trúc này tuy thú vị, nhưng không rõ nó giải quyết vấn đề nêu ở phần đầu bài như thế nào. Nếu thanh toán bị từ chối, có vẻ hệ thống sẽ cung cấp trước các tài nguyên chưa được thanh toán thay vì bảo đảm mọi tài nguyên đều được trả tiền.
Worker tính phí có thể phát hành sự kiện về việc
declinedđể thu hồi tài nguyên, nhưng so với luồng một chiều gọn gàng thì đó sẽ trở thành cấu trúc vòng lặp. Cách này có thể hợp với dịch vụ điện toán tính phí theo tháng như Exe, nhưng là một thỏa hiệp khó chấp nhận với doanh nghiệp giao thiết bị vật lý hoặc bán lại seat của dịch vụ khác.Tuy vậy, bài viết không trả lời trực tiếp cách xử lý lỗi gọi API hoặc lỗi transaction cơ sở dữ liệu, trạng thái đăng ký bất thường, hay việc thanh toán seat bị từ chối. Các vấn đề như refactor làm hỏng việc thu thập phân tích, một số hàng không còn được đánh dấu là đã thay đổi, hoặc đường dẫn mới quên đánh dấu thay đổi vẫn còn nguyên.
Nó cũng không giải quyết được trạng thái liên quan đến tính phí tồn tại bên trong sản phẩm, như giới hạn seat/hạn mức miễn phí, thiết lập mức chi tiêu tối đa, hay trừ vào số dư trả trước. Dịch vụ sản phẩm có thể phát hành sự kiện và dịch vụ tính phí phản ánh lại trạng thái tuân thủ vào sản phẩm, nhưng khi đó trong một hệ thống phân tán có trạng thái sẽ xuất hiện hai tác nhân.
Trông có vẻ Stripe chỉ muốn một con số, nhưng ở quy mô nhất định, nếu cung cấp cả chi tiết từng khoản mục của giao dịch thì có thể giảm phí interchange và tăng tỷ lệ phê duyệt.
Cách Exe không review mã khá mới mẻ. Vậy họ vận hành release và kiểm thử theo cách nào nhỉ?