2

私は現在、レールとMongoidを使用したシンプルなWebベースのゲームの開発に取り組んでいます。解決方法がわからない同時実行の問題が発生しました。

問題は、Mongoidでアトミックにチェックを行い、それに基づいてアクションを実行する方法がわからないことです。

これは、私が何をしようとしているのかを理解するための、コントローラーコードの関連部分のサンプルです。

battle = current_user.battle
battle.submitted = true
battle.save

if Battle.where(opponent: current_user._id, submitted: true, resolving: false).any?
  battle.update_attribute(:resolving, true)
  #Resolve turn

戦闘は2人のユーザー間で行われますが、#Resolveターンを実行するスレッドは1つだけです。これで、完全にオフになっていない限り、両方のスレッドが次々に状態をチェックできますが、resolvingをtrueに設定する前に、両方が「#Resolveturn」コードを実行することになります。

この問題を解決する方法についてのアイデアをいただければ幸いです。

ただし、この方法でユーザーの同期を行うことはかなり非現実的であり、全体としてより良い方法があると感じるようになっています。したがって、同じことを達成できる他の手法の提案をいただければ幸いです。

4

1 に答える 1

3

行をアトミックに取得して更新できるmongofindAndModifyコマンドが必要なようです。

残念ながら、mongoidはmongo apiのこの部分を公開していないように見えるため、この1ビットのドライバーレベルにドロップダウンする必要があるようです。

battle = Battle.collection.find_and_modify(query: {oppenent: current_user._id, ...},
                                           update: {'$set' => {resolving: true})

デフォルトでは、返されるオブジェクトには行われた変更は含まれていませんが、必要に応じてこれをオンにすることができます(pass {:new => true})

返される値は生のハッシュです。私のメモリが正しければBattle.instantiate(doc)Battleオブジェクトを取り戻すために実行できます。

于 2012-04-29T08:23:54.983 に答える