我正在制作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