Vấn đề
Tôi có một biểu mẫu, khi được gửi, sẽ chạy mã cơ bản để xử lý thông tin được gửi và chèn nó vào cơ sở dữ liệu để hiển thị trên trang web thông báo. Ngoài ra, tôi có danh sách những người đã đăng ký nhận những thông báo này qua email và tin nhắn SMS. Danh sách này hiện tại là không đáng kể (chỉ khoảng 150), tuy nhiên, nó đủ để khiến bạn phải mất hơn một phút để lướt qua toàn bộ bảng người đăng ký và gửi hơn 150 email. (Các email đang được gửi riêng lẻ theo yêu cầu của quản trị viên hệ thống của máy chủ email của chúng tôi do các chính sách email hàng loạt.)
Trong thời gian này, cá nhân đã đăng cảnh báo sẽ ngồi ở trang cuối cùng của biểu mẫu trong gần một phút mà không có bất kỳ sự củng cố tích cực nào rằng thông báo của họ đang được đăng. Điều này dẫn đến các vấn đề tiềm ẩn khác, tất cả những gì có giải pháp khả thi mà tôi cảm thấy đều kém lý tưởng.
Đầu tiên, người đăng có thể nghĩ rằng máy chủ đang bị chậm và nhấp lại vào nút 'Gửi', khiến tập lệnh bắt đầu lại hoặc chạy hai lần. Tôi có thể giải quyết điều này bằng cách sử dụng JavaScript để tắt nút và thay thế văn bản để nói điều gì đó như 'Đang xử lý ...', tuy nhiên điều này ít lý tưởng hơn vì người dùng sẽ vẫn bị mắc kẹt trên trang trong suốt thời gian thực thi tập lệnh. (Ngoài ra, nếu JavaScript bị tắt, sự cố này vẫn tồn tại.)
Thứ hai, người đăng có thể đóng tab hoặc trình duyệt sớm sau khi gửi biểu mẫu. Tập lệnh sẽ tiếp tục chạy trên máy chủ cho đến khi nó cố gắng ghi lại vào trình duyệt, tuy nhiên nếu sau đó người dùng duyệt đến bất kỳ trang nào trong miền của chúng tôi (trong khi tập lệnh vẫn đang chạy), trình duyệt sẽ treo trang tải cho đến khi tập lệnh kết thúc . (Điều này chỉ xảy ra khi một tab hoặc cửa sổ của trình duyệt bị đóng chứ không phải toàn bộ ứng dụng trình duyệt.) Tuy nhiên, điều này không lý tưởng hơn.
(Có thể) Giải pháp
Tôi đã quyết định chia nhỏ phần "email" của script thành một tệp riêng biệt mà tôi có thể gọi sau khi thông báo đã được đăng. Ban đầu tôi nghĩ đến việc đưa thông tin này lên trang xác nhận sau khi thông báo đã được đăng thành công. Tuy nhiên, người dùng sẽ không biết tập lệnh này đang chạy và bất kỳ sự bất thường nào sẽ không rõ ràng đối với họ; Tập lệnh này không thể bị lỗi.
Nhưng, điều gì sẽ xảy ra nếu tôi có thể chạy tập lệnh này như một quy trình nền? Vì vậy, câu hỏi của tôi là: Làm thế nào tôi có thể thực thi một tập lệnh PHP để kích hoạt như một dịch vụ nền và chạy hoàn toàn độc lập với những gì người dùng đã thực hiện ở cấp biểu mẫu?
CHỈNH SỬA: Điều này không thể được cron'ed. Nó phải chạy ngay khi biểu mẫu được gửi. Đây là những thông báo có mức độ ưu tiên cao. Ngoài ra, quản trị viên hệ thống đang chạy máy chủ của chúng tôi không cho phép kẻ gian chạy thường xuyên hơn 5 phút.
exec()
nhưng tôi chưa bao giờ thử điều này.
ajax
và chèn sleep()
khoảng thời gian bên trong vòng lặp (tôi sử dụng foreach trong trường hợp của mình) để chạy quy trình nền. Nó hoạt động hoàn hảo trong máy chủ của tôi. Không chắc chắn về những người khác. Tôi cũng đang thêm ignore_user_abort()
và set_time_limit()
(với thời gian kết thúc được tính toán) trước vòng lặp để đảm bảo rằng tập lệnh sẽ không bị dừng bởi máy chủ mà tôi sử dụng, ngay cả theo thử nghiệm của tôi, tập lệnh hoàn thành tác vụ mà không có ignore_user_abort()
và set_time_limit()
.
gearman
với php để giải quyết các tác vụ nền. Nó hoàn hảo để mở rộng quy mô nếu bạn gặp phải quá trình xử lý thời gian lớn và tải nặng. Bạn nên xem xét nó.