Vòng lặp vô tận xảy ra khi kết quả của một luồng lại trở thành sự kiện kích hoạt chính nó, trực tiếp hoặc qua một luồng khác, nên luồng cứ thế chạy mãi cho tới khi hết hạn mức, bị ứng dụng đích chặn, hoặc có người tắt. Đây là lỗi hiếm nhưng tốn kém nhất trong vận hành tự động hoá, vì nó vừa đốt lượt chạy, vừa làm rác dữ liệu, có khi vừa gửi hàng trăm thư cho cùng một người.
Tin tốt là vòng lặp có hình dạng rất đặc trưng, nhận ra được nếu bạn biết nhìn, và cách phòng cũng đơn giản. Bài này giải thích cơ chế bằng ví dụ quen thuộc ở văn phòng nhỏ, việc cần làm trong mười phút đầu khi phát hiện, và vài quy tắc thiết kế giúp vòng lặp không quay lại.
Vòng lặp hình thành thế nào: ba kiểu hay gặp
Kiểu thứ nhất là luồng tự kích hoạt chính nó. Ví dụ giả định: một luồng được dựng để mỗi khi có dòng trong bảng đơn hàng được sửa, nó tự điền ngày cập nhật vào cột cuối. Nhưng chính việc điền ngày cũng là một lần sửa dòng, nên luồng lại chạy, lại điền ngày, lại là một lần sửa. Về lý thuyết nó chạy mãi; trong thực tế nó chạy tới khi công cụ hoặc bảng tính chặn vì quá nhiều yêu cầu.
Kiểu thứ hai là hai luồng đánh qua đánh lại. Luồng A đồng bộ danh sách khách từ ứng dụng bán hàng sang bảng tính. Luồng B đồng bộ ngược từ bảng tính về ứng dụng bán hàng, để nhân viên sửa trên bảng cho tiện. Mỗi lần A ghi vào bảng, B thấy thay đổi và ghi ngược về ứng dụng; ứng dụng báo có thay đổi, A lại ghi vào bảng. Từng luồng riêng lẻ đều đúng; chỉ khi ghép lại mới thành vòng.
Kiểu thứ ba khó thấy hơn: vòng qua hộp thư. Luồng tự trả lời thư đến bằng một thư xác nhận. Nếu người gửi cũng có luồng trả lời tự động, hoặc thư xác nhận vô tình rơi lại vào chính hộp thư đang được theo dõi, hai bên sẽ trả lời nhau liên tục. Nhiều hệ thống thư có cơ chế chặn kiểu này, nhưng không phải lúc nào cũng có và không nên trông vào nó.
Dấu hiệu nhận ra vòng lặp đang chạy
Vòng lặp thường lộ ra trong vòng vài phút đến vài giờ. Những dấu hiệu dưới đây, xuất hiện một hoặc vài cái cùng lúc, là lý do để kiểm ngay:
- Số lượt chạy của một luồng tăng vọt so với bình thường, ví dụ thường vài chục lượt một ngày mà giờ đã vài trăm trong một giờ.
- Lịch sử lượt chạy có rất nhiều lượt liên tiếp, cách nhau vài giây, với dữ liệu đầu vào gần như giống hệt nhau.
- Bảng tính đích phình ra nhanh bất thường, hoặc một ô bị ghi đè liên tục, nhìn thấy giá trị nhảy khi mở bảng.
- Có người nhận được nhiều thư, nhiều tin nhắn giống nhau trong thời gian ngắn và báo lại.
- Công cụ hoặc ứng dụng đích báo đã vượt giới hạn số yêu cầu, hoặc gửi thư cảnh báo sắp hết hạn mức tháng dù mới giữa tháng.
- Hai luồng khác nhau có số lượt chạy tăng cùng lúc và gần bằng nhau, dấu hiệu điển hình của hai luồng gọi nhau.
Nếu bạn đã dựng nhịp kiểm tra số lượt chạy như phần cảnh báo lỗi gợi ý, hãy đặt thêm một ngưỡng trên: số lượt chạy trong một giờ vượt quá một mức bất thường thì báo gấp. Ngưỡng này chặn được phần lớn vòng lặp trước khi chúng gây hại lớn.
Mười phút đầu khi phát hiện vòng lặp
Khi nghi có vòng lặp, ưu tiên là dừng thiệt hại, không phải tìm nguyên nhân. Thứ tự gợi ý:
- Tạm dừng ngay luồng nghi ngờ trong công cụ. Nếu có hai luồng liên quan, tạm dừng cả hai. Tạm dừng chứ không xoá, để còn xem lại cấu hình.
- Nếu không vào được công cụ, hoặc không biết luồng nào gây ra, thu hồi tạm quyền của tài khoản kết nối với ứng dụng đích. Cách này thô nhưng chặn được mọi lượt ghi.
- Kiểm xem vòng lặp đã gửi gì ra ngoài: thư, tin nhắn, thông báo cho khách. Nếu có, chuẩn bị một lời xin lỗi ngắn gửi cho người bị ảnh hưởng.
- Ghi lại thời điểm bắt đầu và kết thúc, số lượt chạy phát sinh, để ước thiệt hại về hạn mức và dữ liệu.
- Sao lưu bảng đích ở trạng thái hiện tại trước khi dọn, phòng khi cần đối chiếu.
- Chỉ sau khi mọi thứ đã đứng yên mới mở cấu hình luồng ra tìm nguyên nhân.
Người nhận cảnh báo cần biết trước bước một và bước hai. Lúc phát hiện vòng lặp thường không có thời gian tra cứu cách tạm dừng; hãy ghi sẵn cách làm trong tài liệu của từng luồng, kèm tên người giữ tài khoản kết nối.
Ba quy tắc thiết kế chặn vòng lặp từ gốc
Luồng không ghi vào chính chỗ nó đang nghe. Nếu luồng kích hoạt khi bảng thay đổi, hạn chế tối đa việc nó ghi lại vào bảng đó. Khi bắt buộc phải ghi, dùng điều kiện để luồng bỏ qua những thay đổi do chính nó tạo ra, ví dụ chỉ chạy khi cột mà người thật nhập liệu thay đổi, không chạy khi cột "ngày cập nhật" thay đổi.
Dùng cờ đánh dấu đã xử lý. Thêm một cột kiểu "luồng đã xử lý". Luồng chỉ chạy với dòng chưa có cờ, và việc đầu tiên sau khi xử lý là đặt cờ. Lần sau dòng đó thay đổi, luồng thấy cờ và bỏ qua. Cờ này cũng giúp chống trùng.
Đồng bộ hai chiều cần một nguồn chân lý. Hai luồng đồng bộ ngược nhau gần như chắc chắn gây vòng nếu không có quy tắc. Tốt nhất chọn một nơi là gốc, chỉ đồng bộ một chiều. Nếu thật sự cần hai chiều, mỗi bản ghi cần thông tin "sửa lần cuối bởi ai" để luồng bỏ qua thay đổi do luồng kia tạo ra. Đây là chỗ đáng nhờ người có kinh nghiệm xem lại thiết kế.
Thử luồng có nguy cơ vòng lặp trước khi bật
Luồng nào vừa nghe vừa ghi vào cùng một nơi, hoặc nằm trong một cặp đồng bộ, đều cần thử riêng cho khả năng vòng lặp. Cách thử đơn giản: dựng trên bảng thử, bật luồng, sửa tay một dòng, rồi quan sát lịch sử lượt chạy trong vài phút. Một lần sửa tay đáng lẽ chỉ sinh đúng một lượt chạy; thấy lượt thứ hai, thứ ba tự xuất hiện là có vòng.
Khi thử cặp luồng đồng bộ, bật cả hai trên dữ liệu thử, sửa một bên, đếm lượt chạy ở cả hai luồng. Nếu số lượt cứ tăng đều sau khi bạn đã ngừng sửa, tắt ngay và xem lại điều kiện. Đặt hạn mức thử thấp nếu công cụ cho phép, để lỡ có vòng lặp thì nó tự dừng sớm.
Với hộp thư, thử bằng cách gửi một thư từ hộp thư thử có bật trả lời tự động tới hộp thư mà luồng đang theo dõi. Quan sát xem hai bên có trả lời nhau quá một lần không. Nếu có, thêm điều kiện bỏ qua thư có dấu hiệu là thư tự động, như tiêu đề bắt đầu bằng cụm trả lời tự động quen thuộc, hoặc người gửi nằm trong danh sách địa chỉ hệ thống.
Đặt sẵn giới hạn an toàn trước khi cần đến
Dù thiết kế cẩn thận, vòng lặp vẫn có thể xuất hiện khi ai đó sửa một luồng mà quên luồng kia. Vài giới hạn đặt sẵn giúp thiệt hại dừng ở mức nhỏ thay vì kéo dài tới khi có người phát hiện:
- Hạn mức chi tiêu hoặc hạn mức lượt chạy ở cấp tài khoản, nếu công cụ cho phép đặt. Hết hạn mức thì luồng dừng, khó chịu nhưng rẻ hơn nhiều so với một hoá đơn vượt mức bất ngờ.
- Ngưỡng cảnh báo số lượt chạy theo giờ cho từng luồng quan trọng, đặt ở mức vài lần so với giờ cao điểm bình thường.
- Giới hạn số thư hoặc tin nhắn gửi cho cùng một người trong một ngày, bằng cách ghi lại người đã nhận và kiểm trước khi gửi. Giới hạn này chặn đúng loại hậu quả làm phiền khách nhất.
- Một công tắc tắt chung: một ô trong bảng cấu hình kiểu "tạm dừng mọi luồng gửi ra ngoài", mà các luồng đều kiểm ở bước đầu. Người không rành công cụ cũng có thể bật công tắc này khi thấy có chuyện.
- Tài liệu ghi rõ ai có quyền tạm dừng từng luồng và cách làm, đặt ở nơi mọi người trong nhóm vận hành đều tìm được.
Những giới hạn này không làm luồng chạy kém đi trong ngày bình thường, vì ngày bình thường không bao giờ chạm tới chúng. Chúng chỉ có tác dụng đúng vào lúc mọi thứ đang trượt khỏi tầm kiểm soát, và đó chính là lúc bạn cần chúng nhất. Việc đặt sẵn tốn chừng nửa giờ cho cả hệ thống luồng của một cửa hàng nhỏ.
Sau sự cố: dọn dẹp và rút kinh nghiệm
Vòng lặp thường để lại ba loại hậu quả cần dọn. Dữ liệu rác trong bảng đích: dòng trùng, ô bị ghi đè nhiều lần, có khi giá trị cuối cùng sai. Hạn mức bị đốt: số lượt chạy trong tháng giảm mạnh, có thể ảnh hưởng tới các luồng khác dùng chung tài khoản. Và người nhận bị làm phiền: khách hay đồng nghiệp nhận thư, tin nhắn lặp lại.
Với dữ liệu, dùng bản sao lưu trước sự cố nếu có, hoặc lọc theo thời điểm để tách các dòng sinh ra trong lúc vòng lặp chạy, rồi rà lại. Với hạn mức, kiểm xem các luồng mức gấp còn đủ lượt cho tới cuối kỳ không; nếu không, cân nhắc tạm dừng luồng mức thấp hoặc liên hệ nhà cung cấp công cụ. Chi phí phát sinh, nếu có, nên được ghi lại kèm nguyên nhân.
Cuối cùng, ghi một đoạn ngắn vào sổ sự cố: vòng lặp hình thành thế nào, phát hiện bằng cách nào, mất bao lâu để dừng, đã thêm quy tắc gì để chặn. Lần sau có ai dựng luồng tương tự, đoạn ghi chép này giúp họ tránh đúng cái bẫy đó. Một buổi rút kinh nghiệm không nhằm tìm người có lỗi; vòng lặp thường sinh ra từ hai luồng mà từng cái đều được dựng đúng.
Câu hỏi thường gặp
Vòng lặp vô tận trong luồng tự động là gì?
Là khi kết quả của một luồng lại kích hoạt chính nó, trực tiếp hoặc qua một luồng khác, khiến luồng chạy liên tục. Ví dụ luồng điền ngày cập nhật mỗi khi dòng được sửa, nhưng việc điền ngày cũng là một lần sửa, nên nó lại chạy.
Làm sao biết luồng đang bị vòng lặp?
Số lượt chạy tăng vọt trong thời gian ngắn, lịch sử có nhiều lượt cách nhau vài giây với dữ liệu gần giống nhau, bảng đích phình nhanh, có người nhận nhiều thư giống hệt, hoặc công cụ báo vượt giới hạn yêu cầu dù mới giữa tháng.
Phát hiện vòng lặp thì làm gì đầu tiên?
Tạm dừng ngay luồng nghi ngờ, cả hai luồng nếu có hai luồng liên quan. Nếu không vào được công cụ, thu hồi tạm quyền tài khoản kết nối. Tìm nguyên nhân để sau, khi mọi thứ đã dừng và bạn đã sao lưu dữ liệu hiện tại.
Đồng bộ hai chiều giữa bảng tính và ứng dụng bán hàng có nên làm không?
Nên tránh nếu có thể, vì rất dễ thành vòng lặp và khó biết bên nào đúng. Chọn một nơi làm gốc và chỉ đồng bộ một chiều. Nếu bắt buộc hai chiều, cần cơ chế bỏ qua thay đổi do luồng kia tạo ra, và nên nhờ người có kinh nghiệm xem lại.
Cờ đánh dấu đã xử lý giúp gì?
Cờ là một cột ghi rằng dòng này đã được luồng xử lý. Luồng chỉ chạy với dòng chưa có cờ và đặt cờ ngay sau khi xử lý. Nhờ vậy thay đổi do chính luồng gây ra không kích hoạt lại nó, đồng thời giảm khả năng chạy trùng.
Vòng lặp có làm tốn tiền không?
Có thể có. Với gói tính theo số lượt chạy, vòng lặp đốt hạn mức rất nhanh và có thể làm phát sinh phí vượt mức tuỳ điều khoản. Đặt ngưỡng cảnh báo số lượt chạy theo giờ và hạn mức thấp khi thử là cách giới hạn thiệt hại.