Chuyển đến nội dung
MINH VO Ghi chép từ công việc
của một kỹ sư tại Việt Nam
Cơ bản11 phút đọc

Vẽ trách nhiệm phía sau một tính năng full stack

Phân chia trách nhiệm của tính năng xuất báo cáo, từ giao diện đến lưu trữ, rồi kiểm tra trường hợp thu hồi quyền và công việc bị kẹt.

Tranh màu nước vẽ những cuốn sổ, một quyển sổ mở và bút chì trên nền màu kem

Một tính năng full stack dễ thảo luận hơn khi bạn vẽ ra các quyết định mà từng phần chịu trách nhiệm. Tôi thích làm việc đó trước khi chia đầu việc hoặc chọn dịch vụ. Sơ đồ thành phần cho biết mã chạy ở đâu; bản đồ trách nhiệm còn cho biết ai định nghĩa hành vi khi yêu cầu thất bại, phải chờ hoặc đi qua ranh giới bảo mật.

Xét tính năng xuất báo cáo giả định. Người dùng yêu cầu báo cáo, chờ một tiến trình nền tạo tệp rồi tải kết quả về. Trong dự án học tập, giao diện, API, tiến trình nền và nơi lưu trữ có thể do một người làm hết. Chúng vẫn có trách nhiệm khác nhau. Bỏ sót một trách nhiệm có thể tạo ra tính năng trông đã hoàn thành nhưng chưa rõ cách khôi phục khi gặp lỗi.

Bắt đầu từ điều hứa với người dùng

Viết một câu về điều sản phẩm cung cấp: “Yêu cầu báo cáo cho những bản ghi bạn có quyền truy cập, rồi tải tệp đã hoàn thành khi sẵn sàng.” Câu đó chứa nhiều quyết định chưa được nói rõ.

Người dùng được truy cập những bản ghi nào? Việc xuất dùng quyền tại thời điểm yêu cầu hay lúc tải? Tệp được giữ bao lâu? Điều gì xảy ra nếu tiến trình nền đã tạo tệp nhưng dừng trước khi ghi nhận hoàn thành? Người dùng phân biệt một yêu cầu đang xếp hàng với yêu cầu đã bị mất như thế nào?

Bạn chưa cần trả lời hết ngay. Đặt mỗi câu hỏi cạnh phần hệ thống có thể thực thi câu trả lời. Quyết định sản phẩm về thời hạn lưu phải xuất hiện trong hợp đồng hành vi, còn cấu hình lưu trữ và mã dọn dẹp phải thực hiện nó. Nếu không ai chịu trách nhiệm nối hai phía, cuộc trao đổi về “việc lưu tệp” có thể bỏ qua yêu cầu thực sự.

Ghép quyết định với bằng chứng

Bản đầu tiên có thể nối quyết định với bằng chứng như sau:

Ranh giớiQuyết định chịu trách nhiệmBằng chứng cần xem
Giao diệnCách giải thích trạng thái chờ, lỗi và hoàn thànhCác bước hiển thị từng trạng thái và hành động xử lý tiếp dùng được
APIAi được yêu cầu báo cáo nào và nhận mã gìTrường hợp được phép và không được phép
Tiến trình nềnCách công việc đổi trạng thái và xử lý lần thử khácChuỗi trạng thái có cả lần thực hiện bị gián đoạn
Lưu trữAi được tải tệp và khi nào tệp hết hạnKiểm tra truy cập và quy tắc lưu giữ rõ ràng
Vận hànhCách phát hiện công việc bị kẹt và ai xử lýTín hiệu, người phụ trách và quy trình điều tra đã kiểm tra

Kiến trúc khác có thể đặt một số trách nhiệm ở chỗ khác. Mối liên hệ cần giữ là giữa quyết định và bằng chứng cho thấy cách triển khai tuân theo quy tắc dự định.

Yêu cầu xuất đi qua giao diện, API, tiến trình nền và lưu trữ; bên vận hành theo dõi công việc bị kẹt, còn đường tải kiểm tra lại quyềnMở ảnh kích thước đầy đủ ↗

Nhánh vận hành bổ sung rất quan trọng. Công việc có thể ở trạng thái chờ mãi mà không phát sinh ngoại lệ rõ ràng. Nếu giao diện cứ hỏi lại trạng thái, người dùng có thể chờ vô hạn trong khi từng thành phần đều có vẻ vẫn chạy.

Tìm các điểm bàn giao cần thống nhất hành vi

Giả sử API trả về mã công việc trước khi tiến trình nền bắt đầu. Giao diện cần biết sẽ nhận những trạng thái nào khi hỏi mã đó. Tiến trình nền cần biết thử lại có được tạo thêm tệp khác hay không. Nơi lưu trữ cần quy tắc cho những đối tượng còn lại sau lần thực hiện bị gián đoạn.

Viết thỏa thuận bằng hành vi quan sát được. “Tiến trình nền phải đáng tin cậy” quá rộng. “Một lần thử lại cho công việc đã hoàn thành không được công bố hai kết quả tải khác nhau” là điều kiện mọi người có thể kiểm tra, dù cách triển khai vẫn cần được thiết kế.

Hướng dẫn review kỹ thuật của Google hỏi thiết kế của thay đổi có phù hợp với hệ thống và chức năng có đúng nhu cầu hay không. Bản đồ trách nhiệm giúp người review tìm hành vi xung quanh mà một bản sửa cục bộ có thể ảnh hưởng. Đổi tên trạng thái của tiến trình nền cũng thay đổi cách giao diện diễn giải, trừ khi có lớp chuyển đổi giữ nguyên hợp đồng.

Giao rõ người phụ trách phần còn thiếu

Bản đồ chỉ hữu ích nếu dẫn tới một hành động. Đánh dấu quyết định chưa thống nhất một cách cụ thể, thay vì đặt vào ô “để sau”. Chẳng hạn, bản phát hành đầu chưa thống nhất thời hạn lưu tệp. Đây là câu hỏi về sản phẩm và vận hành cần giải quyết trước khi các tệp vô tình được giữ mãi.

Trong nhóm, phân biệt người triển khai thay đổi với người có thẩm quyền quyết định chính sách. Lập trình viên có thể viết mã xóa, còn bên sản phẩm hoặc pháp lý đưa ra yêu cầu lưu giữ. Với dự án cá nhân để học, bạn có thể tự quyết định nhưng vẫn nên ghi giả định đó.

Chương Google SRE về mục tiêu mức dịch vụ giải thích vai trò của chỉ số và mục tiêu trong việc mô tả hành vi dịch vụ. Ở ví dụ này, chỉ số hữu ích có thể là số báo cáo hoàn thành trong thời gian đã thống nhất. Chỉ đo tiến trình có đang chạy không sẽ chưa trả lời được người dùng có nhận tệp hay không.

Giữ bản đồ vừa đủ cho tính năng

Cách làm này có thể trở nên rườm rà nếu mỗi hàm hỗ trợ đều có một ô trách nhiệm riêng. Vẽ ranh giới tại nơi lời hứa thay đổi, quyền truy cập thay đổi hoặc lỗi cần cách phản ứng khác. Với bản thử cục bộ, một trang và vài chuỗi trạng thái có thể đã đủ.

Trước khi triển khai, nhờ người khác theo một yêu cầu qua bản đồ và chỉ ra ai phụ trách khi báo cáo bị kẹt. Nếu họ phải đoán, sửa phần đó. Sau khi triển khai, so sánh chuỗi yêu cầu và công việc thực tế với bản vẽ. Bản đồ có giá trị khi giúp tìm hành vi còn thiếu hoặc làm cho điểm bàn giao dễ review hơn.

Thử bản đồ với quyền truy cập thay đổi giữa chừng

Bản đồ trách nhiệm hữu ích hơn khi bạn đưa một chuỗi sự kiện khó qua nó. Giả sử người dùng yêu cầu xuất khi còn là thành viên của một không gian làm việc. Công việc vẫn đang xếp hàng. Trước khi tiến trình nền bắt đầu, người dùng bị thu hồi tư cách thành viên. Tiến trình sau đó tạo ra tệp. Ai quyết định người dùng có được tải không?

Với sản phẩm giả định này, chọn một chính sách rõ ràng: người đã bị thu hồi quyền không còn được tải báo cáo của không gian đó. Lựa chọn này chưa tự quyết định tiến trình nền phải hủy, hoàn thành cho người khác còn quyền hay xóa kết quả. Đó là các quyết định bổ sung cần người phụ trách.

Thời điểmQuyết định cần đưa raRanh giới có thể thực thi
Chấp nhận yêu cầuNgười dùng có được yêu cầu báo cáo này không?Kiểm tra quyền tại API
Xóa tư cách thành viênQuyền nào chấm dứt và từ lúc nào?Chính sách sản phẩm và mô hình thành viên
Tiến trình nền bắt đầuCông việc đang chờ còn cần thiết và được phép không?Hợp đồng công việc và hành vi tiến trình
Yêu cầu tảiNgười gọi hiện có được lấy kết quả không?Kiểm tra quyền truy xuất
Giữ kết quảAi được truy cập đối tượng và trong bao lâu?Cách triển khai quyền lưu trữ và thời hạn lưu

Hướng dẫn kiểm tra quyền truy cập của OWASP đề nghị kiểm tra quyền trên các yêu cầu. Trong chuỗi này, kiểm tra ở yêu cầu ban đầu chưa đủ thực hiện chính sách tải đã chọn. Phải xem xét cả đường lấy kết quả.

Yêu cầu xuất được cho phép, tư cách thành viên bị thu hồi sau đó và yêu cầu tải kiểm tra chính sách hiện tại; quyết định của tiến trình nền và thời hạn lưu đều có bên phụ tráchMở ảnh kích thước đầy đủ ↗

Hình tách quyết định chính sách khỏi mã thực thi. Lập trình viên có thể triển khai một quy tắc rõ ràng, nhưng không nên âm thầm quyết định ngữ nghĩa truy cập của sản phẩm chỉ vì thư viện lưu trữ khiến một cách làm thuận tiện hơn.

Phân biệt người quyết định với người triển khai

Người viết tiến trình nền có thể không có thẩm quyền quyết định báo cáo chứa dữ liệu nhạy cảm được giữ bao lâu. Người định nghĩa thời hạn lưu có thể chưa biết cơ chế dọn dẹp nào thực hiện được yêu cầu một cách đáng tin cậy. Cần cả hai đóng góp, và bản đồ nên thể hiện mối nối đó.

Trong nhóm nhỏ, một người có thể giữ nhiều trách nhiệm. Vẫn nên viết tách chúng ra. Khi review, mọi người có thể hỏi chính sách đã thực sự được chọn chưa và mã có tuân theo nó không. Trong dự án cá nhân, bạn tự quyết định được, nhưng quy tắc thành văn vẫn tránh để tính năng sau dựa vào giả định khác.

Một lần bàn giao hữu ích có quy tắc, ví dụ liên quan và trường hợp biên còn chưa giải quyết. Với người bị thu hồi quyền, lập trình viên backend cần biết một quyền tải đã cấp trước đó có thể tiếp tục tồn tại sau khi mất tư cách thành viên hay không, và điều đó ảnh hưởng thế nào đến chính sách. Câu trả lời phụ thuộc cơ chế truy cập, không thể suy ra từ tên endpoint.

Tính cả kết quả còn lại sau lần thực hiện lỗi

Bây giờ xét tiến trình nền đã ghi tệp nhưng dừng trước khi đánh dấu công việc hoàn thành. Giao diện vẫn báo chờ, còn nơi lưu trữ đã có đối tượng. Thành phần nào nhận diện được đối tượng đó, quyết định có thể dùng lại không và xóa nếu cần?

Liên kết đối tượng với một mã công việc ổn định hoặc quan hệ khác có thể kiểm tra. Thiếu quan hệ đó, tiến trình dọn dẹp có thể không phân biệt được tệp bị bỏ lại với kết quả vẫn được sử dụng. Quy tắc lưu giữ cũng cần một mốc bắt đầu: lúc tạo, lúc công việc hoàn thành hay lần truy cập hợp lệ cuối sẽ dẫn tới thời điểm xóa khác nhau.

Bản đầu có thể chọn quy tắc đơn giản, như xóa đối tượng tạm không còn được tham chiếu sau một khoảng thời gian giới hạn trong môi trường thực hành. Nó vẫn phải nhận diện được các đối tượng đó và tránh xóa kết quả đã được chấp nhận. Ghi giả định và kiểm tra lần thực hiện bị lỗi riêng với lần xuất hoàn thành bình thường.

Để quá trình review đi theo lỗi qua nhiều bên phụ trách

Nhờ người review bắt đầu từ “người dùng không tải được báo cáo” và lần theo bằng chứng đang có. Họ có nhận diện được công việc, các lần thử và đối tượng kết quả không? Có biết người dùng hiện còn quyền không? Có bên phụ trách rõ ràng cho công việc chờ mà không có tiến trình nào thực hiện không?

Nếu điều tra dừng ở ranh giới nhóm, thêm điểm bàn giao hoặc khả năng quan sát còn thiếu. Điều đó chưa chắc cần dịch vụ hay bảng điều khiển mới. Một mã ổn định, sự kiện được ghi chính xác và người phụ trách đã thống nhất có thể đủ. Bản đồ trách nhiệm nên giúp giải quyết yêu cầu khó, thay vì tạo thêm một sơ đồ tổ chức không ai dùng lúc xảy ra lỗi.

Nguồn tham khảo & đọc thêm

  1. Google SRE: service level objectives
  2. Google Engineering Practices: what to look for in a review
  3. OWASP: authorization cheat sheet
← Về trang bài viết

Hình minh họa

100%