我正在製作Google應用程序引擎的成績簿。我跟蹤每個學生的評分等級。評分時段可以重疊。由於我可能一次顯示數百個這樣的等級,因此我會預先計算服務器上的等級。所以,對於任何一個學生,我可能有很多計算成績 - 每個成績階段一個。找到缺陷!使用任務隊列可靠地執行長期任務
現在,老師從測驗中輸入新分數。該分數可能會影響許多計算成績,因爲它可能會落入許多分數階段。我需要重新計算所有受影響的成績。這可能需要很長時間,因爲在每個評分階段,我需要獲取所有相關分數,並對這些分數執行復雜的例程。我認爲30秒是不夠的 - 特別是如果數據存儲今天感覺緩慢。此外,失敗不是一種選擇。更新某些等級並使其他人無聲無息地過期是不可接受的。
因此,我認爲對於自己來說,瞭解任務隊列是多麼美妙的時刻!
我不是在數據庫結構或任何方面的專家,但這裏是什麼,我希望做一個概要:
public ReturnCode addNewScore(Float score, Date date, Long studentId)
{
List<CalculatedGrade> existingGrades = getAllRelevantGradesForStudent(studentId, date);
for (CalculatedGrade grade : existingGrades)
{
grade.markDirty(); //leaves a record that this grade is no longer up to date
}
persistenceManager.makePersistentAll(existingGrades);
//DANGER ZONE?
persistenceManager.makePersistent(new IndividualScore(score, date, studentId));
tellTheTaskQueueToStartCalculating();
return OMG_IT_WORKED;
}
這似乎是一個快速的方法,以紀念所有相關等級髒的。如果中途失敗,則返回失敗,客戶將知道再次嘗試。如果客戶稍後嘗試獲取髒分,我們可以在那裏返回錯誤。
然後,任務隊列的代碼會是這個樣子:
public void calculateThemGrades()
{
List<CalculatedGrade> dirtyGrades = getAllDirtyGrades();
try
{
for (CalculatedGrade grade : dirtyGrades)
{
List<Score> relevantScores = getAllRelevantScores();
Float cleanGrade = calculateGrade(relevantScores);
grade.setGrade(cleanGrade);
grade.markClean();
persistenceManager.flush();
}
}
catch(Throwable anything)
{
//if there was any problem, like we ran out of time or the datastore is down or whatever, just try again
tellTheTaskQueueToStartCalculating()
}
}
我的問題是:這是否保證絕不會有被標記乾淨的新成績已經加入後,計算成績?
關注的具體領域:
- 將在
existingGrades
始終在第一個片段的新IndividualScore
之前堅持着,周圍的危險區? - 是否有可能另一個線程將在危險區域啓動任務隊列代碼,以便在真正進入新的
IndividualScore
之前,那些現有的Graded可能會被標記爲乾淨?如果是這樣,我怎樣才能確保不會發生(所有成績的交易都沒有)? - 是否
persistenceManager.flush()
足以保存部分完成的計算,即使pm未關閉?
這一定是常見的問題。我會很感激任何教程鏈接,尤其是那些appengine。感謝您閱讀這麼多!
我有一個產品做心理測試。用戶通過測試輸入原始數據,並在構建報告時進行復雜計算循環。儘管成千上萬的方程與您所做的類型非常相似,但即使在同時支持多個用戶的情況下,也幾乎沒有任何滯後。如果這只是你使用這個,你可能會有點矯枉過正.... – bpeterson76 2011-02-24 23:09:57
感謝您的觀點。我希望每次計算都需要獲取大約1000個實體,包括分數和其他一些東西,然後平均返回10個實體。可能這可能會在單個請求中運行,但我需要永遠不會將數據保留在不一致狀態的內容。它正在處理我開始擔心時間不夠的錯誤 - 我偶爾會在其他一些請求中耗盡時間。 – 2011-02-24 23:14:35
嗯...但是,我想我可以做更多的計算時,實際要求的成績,如果失敗返回相同的錯誤信息,否則我... – 2011-02-24 23:33:45