GoogleAppEngineで成績表を作成しています。私は、評価期間ごとに各学生の成績を追跡します。採点期間は重複する可能性があります。一度に数百のこれらの成績を表示する可能性があるため、サーバーで成績を事前に計算します。したがって、1人の学生に対して、私は多くの計算された成績を持っている可能性があります-各成績期間に1つ。
これで、教師はクイズから新しいスコアを入力します。そのスコアは、多くの評価期間に分類される可能性があるため、計算された評価の多くに影響を与える可能性があります。影響を受けるすべてのグレードを再計算する必要があります。採点期間ごとに、関連するすべてのスコアを取得し、それらのスコアに対して複雑なルーチンを実行する必要があるため、これには長い時間がかかる可能性があります。30秒では不十分だと思います。特に、今日のデータストアの速度が遅い場合はなおさらです。さらに、失敗はオプションではありません。一部のグレードが更新され、他のグレードが黙って古くなることは容認できません。
ですから、タスクキューについて学ぶのに最高の時間だと思います。
私はDB構造などの専門家ではありませんが、私がやりたいことの概要は次のとおりです。
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
別のスレッドが危険ゾーンでタスクキューコードを開始して、新しいものが実際に入力される前に、それらの既存のグレードが再びクリーンとマークされる可能性はありますか?もしそうなら、どうすればそれが起こらないようにすることができますか(すべてのグレードのトランザクションがアウトになっています)?persistenceManager.flush()
午後が閉じていなくても、部分的に行われた計算を保存するのに十分ですか?
これは一般的な種類の問題であるに違いありません。チュートリアル、特にappengineのチュートリアルへのリンクをいただければ幸いです。たくさん読んでくれてありがとう!