我將我的站點移植到python/django,其中一個主要練習涉及一組數據,用戶可以在其當地時間安排一個事件,並且它每天都在發生。Django:每天在指定用戶當地時間運行一個進程
目前我有一個cron工作(在另一臺服務器上),每隔5分鐘就打一個方法,看看是否需要安排下一個(比如說)10分鐘。
我保存時間值,併爲每個作業
什麼是做到這一點的最佳方式在用戶的本地時區?
現在我工作的一個函數:
- 服務器時間轉換到用戶本地時間。
- 創建本地日期時間對象本地化的「今天」和用戶指定的時間
- 檢查它是否在用戶警報關閉的10分鐘內。
- 如果它在23:50-23:59:59之間,並且用戶的設置時間是00:00-00:10 本地化的「今天」是用「明天」的日期創建的。 (例如,如果 爲2分鐘至午夜,用戶希望在 12:01有一個事件,我計算與明天的日期的事件)
- 我定當它被安排了 last_scheduled場和last_fired場到 確保我不發送倍數。
如果距離現在還不到10分鐘,我會安排一個即將開火的任務(線程,無論什麼)。
這裏的最佳做法並不確定。我應該:
繼續檢查,看看我是否有將來的任務,並安排短期任務?
提前生成我所有的時間(可能一個月一次嗎?)
完成其他操作嗎?
我也在想我總是可以安排「下一個」事件,但我擔心的是,如果說我的服務器脫機了,而我錯過了「下一個」事件,那麼第二天永遠都不會安排。
澄清:
- 我儲存的時間和每個作業時區(如中午在美國/東部)。
- 我正在爲DST進行更正,因此在計算UTC時間時,我將utc的當天日期轉換爲當地時間,然後使用它計算增量值。我使用pytz和normalize()來確保我沒有遇到任何不可靠的DST問題。
- 我確實有最後一次預定時間和最後一次運行時間,以確保我不會執行兩次。
看着下面的解決方案,我想我唯一的其他看法是,如果出於某種原因,我錯過了預定的時間,我的「下一個」永遠不會發生,因爲它是那麼過去。我想我可以做第二個功能來修復任何錯過的警報。
編輯: 所著的Grokking下面的答案後,我想出了以下不太糟糕的情況下:
我有以下字段
- 上次事件執行時間
- 最後時間事件安排
- 下一個事件執行時間
- 時間和時區
我每當我計算並設置next_run_time:更新事件或觸發事件。 此執行以下操作:
- 如果它有一個最後的運行時,next_run_time計算,至少2,今後小時(避免DST問題通過添加一些填充)。
- 如果事件從未運行,在未來的時間表至少15分鐘(避免多個同時時間表)
我的計劃作業執行以下操作:
- 檢查有所有事件next_run_time在接下來的15分鐘內,並且目前沒有安排。任何匹配都是預定的。
調度作業:
- 計劃任務,並將任務如期 「現在」
執行任務時(成功):
- last_run_time更新爲「現在」
- next_run_time重新計算
如果任務失敗: - 作業將在未來重新計劃30秒。如果失敗超過閾值(在我的情況下過期3分鐘),任務將中止,next_run_time將在第二天重新計算。這得到記錄,並希望不會發生太大
這似乎大多是工作,因爲我的活動總是(每日),這樣我就可以買得起扔在了時代的一些空隙,以防止有些發毛的問題
欣賞任何信息在這裏。爲了說明我在當地時間存儲以避免DST問題,並且確實有例如每日00:00紐約。我有一個to_next_utc_time()函數,它給了我下一個運行時間,在now() – Yablargo
之後,我實際上已經在.net端實現了Quartz解決方案。我只是不能證明跳過一些偉大的/便宜的Linux託管。 FWIW,但是我在日常工作中在生產中運行單聲道應用程序,在heroku上單聲道很誘人。感謝Apscheduler鏈接,我想我會在這裏至少將解決方案納入解決方案的一半。 – Yablargo