Giả sử tôi có một mô hình Event
. Tôi muốn gửi thông báo (email, đẩy, bất cứ điều gì) cho tất cả người dùng được mời khi sự kiện đã kết thúc. Một cái gì đó dọc theo dòng:
class Event(models.Model):
start = models.DateTimeField(...)
end = models.DateTimeField(...)
invited = models.ManyToManyField(model=User)
def onEventElapsed(self):
for user in self.invited:
my_notification_backend.sendMessage(target=user, message="Event has elapsed")
Bây giờ, tất nhiên, phần quan trọng là để gọi onEventElapsed
bất cứ khi nào timezone.now() >= event.end
. Hãy ghi nhớ, end
có thể là vài tháng kể từ ngày hiện tại.
Tôi đã nghĩ về hai cách cơ bản để làm điều này:
Sử dụng một
cron
công việc định kỳ (giả sử, cứ sau năm phút hoặc lâu hơn) để kiểm tra xem có bất kỳ sự kiện nào đã trôi qua trong vòng năm phút cuối và thực hiện phương pháp của tôi không.Sử dụng
celery
và lên lịchonEventElapsed
sử dụngeta
tham số sẽ được chạy trong tương lai (trongsave
phương thức mô hình ).
Xem xét lựa chọn 1, một giải pháp tiềm năng có thể django-celery-beat
. Tuy nhiên, có vẻ hơi lạ khi chạy một tác vụ ở một khoảng thời gian cố định để gửi thông báo. Ngoài ra, tôi đã đưa ra một vấn đề (tiềm năng) có thể (có thể) dẫn đến một giải pháp không thanh lịch:
- Kiểm tra cứ năm phút cho các sự kiện đã trôi qua trong năm phút trước? có vẻ run rẩy, có thể một số sự kiện bị bỏ lỡ (hoặc những sự kiện khác nhận được thông báo của họ gửi hai lần?). Workaroung tiềm năng: thêm trường boolean vào mô hình được đặt thành
True
một khi thông báo đã được gửi.
Sau đó, một lần nữa, tùy chọn 2 cũng có vấn đề của nó:
- Tự xử lý tình huống khi thời gian bắt đầu / kết thúc sự kiện được di chuyển. Khi sử dụng
celery
, người ta sẽ phải lưu trữtaskID
(dễ dàng, ofc) và thu hồi tác vụ một khi ngày đã thay đổi và đưa ra một nhiệm vụ mới. Nhưng tôi đã đọc, rằng cần tây có vấn đề (cụ thể về thiết kế) khi xử lý các tác vụ được chạy trong tương lai: Vấn đề mở trên github . Tôi nhận ra làm thế nào điều này xảy ra và tại sao nó là tất cả nhưng tầm thường để giải quyết.
Bây giờ, tôi đã đi qua một số thư viện có khả năng giải quyết vấn đề của tôi:
- celery_longterm_scheduler (Nhưng điều này có nghĩa là tôi không thể sử dụng cần tây như trước đây, vì lớp Trình lập kế hoạch differend? Điều này cũng liên quan đến việc sử dụng
django-celery-beat
... Sử dụng bất kỳ hai khung công tác nào, vẫn có thể xếp hàng công việc (mà chỉ chạy lâu hơn một chút chứ không phải vài tháng nữa?) - django-apscheduler , sử dụng
apscheduler
. Tuy nhiên, tôi không thể tìm thấy bất kỳ thông tin nào về cách nó sẽ xử lý các tác vụ được chạy trong tương lai xa.
Có một lỗ hổng cơ bản với cách tôi đang tiếp cận điều này? Tôi vui mừng cho bất kỳ đầu vào bạn có thể có.
Lưu ý: Tôi biết điều này có thể là một số ý kiến dựa trên, tuy nhiên, có thể có một điều rất cơ bản mà tôi đã bỏ lỡ, bất kể những gì có thể được coi là xấu xí hay thanh lịch.