視圖依賴於Redis來填充。 Redis由每10分鐘運行一次的管理命令填充。該管理命令將刪除所有現有密鑰並重新添加新數據。我如何確定管理命令是否從django視圖運行?有沒有辦法檢查Django管理命令是否正在運行?
現在我正在將管理命令寫入外部文件,並讓每個請求都有一個讀取該文件的視圖。如果數據庫通過管理命令刷新,我會保持視圖直到完成(輪詢樣式)。
視圖依賴於Redis來填充。 Redis由每10分鐘運行一次的管理命令填充。該管理命令將刪除所有現有密鑰並重新添加新數據。我如何確定管理命令是否從django視圖運行?有沒有辦法檢查Django管理命令是否正在運行?
現在我正在將管理命令寫入外部文件,並讓每個請求都有一個讀取該文件的視圖。如果數據庫通過管理命令刷新,我會保持視圖直到完成(輪詢樣式)。
Django不提供預先打包的方式來檢查管理命令是否正在運行。這就是說,你永遠不應該寫代碼,在等待某些結果時顯式地阻止視圖。您可以輕鬆使用運行應用程序的服務器提供給應用程序的所有線程和進程。您的用戶在您的網站上的體驗不佳,即使那些與您在此嘗試解決的問題沒有任何關係的用戶也可能遇到困難。
我從你的描述中得到的結果是,你希望用戶得到合理的新鮮結果。對於這樣的事情,我會使用基於versioning數據的解決方案。它會是這樣的:
聲明一個Redis的備份緩存在settings.py
文件,將包含由命令填充,由視圖讀取數據。確保緩存的TIMEOUT
設置爲NONE
。
當前版本號與密鑰CURRENT_VERSION
一起記錄。這個關鍵本身沒有版本。
當命令刷新緩存中的數據時,會將其存儲在版本設置爲CURRENT_VERSION + 1
的密鑰中。你會碰到這樣的:
current_version = cache.get(CURRENT_VERSION)
# Record the new data.
for ...:
cache.set(some_key, some_value, version=current_version + 1)
Django的緩存系統不容易允許獲得一組對應於特定的標準鍵。但是,您的視圖將希望獲取屬於特定版本的所有密鑰。可以記錄這些信息爲:
cache.set(ALL_RECORDS,
[... list of keys set in the loop above ...],
version=current_version + 1)
哪裏ALL_RECORDS
是保證不會CURRENT_VERSION
或任何對個人記錄設置的按鍵衝突的關鍵值。
一旦命令完成,它以原子增加CURRENT_VERSION
值:
cache.incr(CURRENT_VERSION)
對Redis的後端的文檔指出,如果你在適當的值進行增量(剩下的含糊,但整數似乎適當),那麼Redis將以原子方式執行增量。
該命令還應該清理緩存中的舊版本。確保舊數據不會保留在高速緩存中的一種方法是在設置其值時設置密鑰的到期時間。刷新緩存的命令每10分鐘運行一次。因此,您將密鑰設置爲在15分鐘後過期。但是,假設一個問題阻止了多次運行該命令的運行。然後怎樣呢?您的數據將過期並從緩存中刪除,並且視圖將以空數據集運行。如果這是好您的情況,那麼我想你可以在每次做cache.set
,除了CURRENT_VERSION
應該永不過期時間的設置參數timeout
。
如果你不行你的看法有一個空的數據集運行(這似乎更可能對我來說),那麼你必須在你的命令,尋求舊版本,並明確地刪除它們編寫代碼。
您的觀點通過訪問高速緩存:
讀的CURRENT_VERSION
值:
keys = cache.get(ALL_RECORDS, version=current_version)
:它得到了版本讀取的記錄列表 current_version = cache.get(CURRENT_VERSION)
個處理記錄:
for key in keys:
value = cache.get(key, version=current_version)
視圖應檢測其中緩存尚未初始化和優雅地失敗的情況。在部署應用程序時,應該注意,在訪問站點之前,命令至少運行過一次。
如果視圖開始,而命令更新緩存工作,也沒關係。從命令的角度來看,緩存只是訪問以前的版本。從視圖來看,該命令正在忙於創建下一個版本,但這對視圖是不可見的。該視圖不必阻止。
您希望以檢測該命令正在運行,但必須在命令檢測到一個視圖訪問數據? – Louis
不是。該命令不需要知道該信息。只有視圖需要知道管理命令是否正在運行。 – ubunix
爲什麼視圖需要知道管理命令是否正在運行? (我有什麼樣的答案可能是一個想法,但我不想承擔。) – Louis