2012-04-29 2 views
2

В настоящее время я пытаюсь изо всех сил разрабатывать простую веб-игру с использованием рельсов и монгоидов. Я столкнулся с некоторыми проблемами параллелизма, которые я не знаю, как их решить.Concurrency and Mongoid

Проблема в том, что я не уверен, как атомизировать проверку и принять меры, основанные на ней в 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 

битва между двумя пользователями, но я хочу только одну из потоки для запуска поворота #Resolve. Теперь, если я не отключу оба потока, можно проверить условие один за другим, но прежде чем устанавливать разрешение на истину, поэтому оба заканчивают работу кодом «#Resolve turn».

Я был бы очень признателен за любые идеи о том, как решить эту проблему.

Тем не менее, я все больше чувствую, что синхронизация пользователя таким образом довольно непрактична и что есть лучший способ. Поэтому были бы очень полезны предложения по другим методам, которые могли бы выполнить одно и то же.

ответ

3

Похоже, вы хотите команду mongo findAndModify, которая позволяет вам атомизировать и обновлять строку.

К сожалению Mongoid не появляется, чтобы выставить эту часть Монго API, так что похоже, вам придется опуститься до уровня драйвера для этого один бит:

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

По умолчанию возвращенного объект не включают модификацию сделали, но вы можете включить эту опцию, если вы хотите (пропуск {: новый => верно})

Возвращаемое значение является исходным хэш, если моя память правильно вы можете сделать Battle.instantiate(doc) чтобы вернуть объект Battle.

+0

Привет! Спасибо за ваш ответ. Однако я не мог заставить эту команду работать. Выходной результат: Mongo :: OperationFailure (команда базы данных «findandmodify» не выполнена: (errmsg: «no such cmd»; bad cmd: '{"findandmodify" => "battles", "query" => {"enemy" => BSON :: ObjectId ('4f970eb047911507fe000205'), "submitted" => true}, "update" => {"$ set" => {"resolving" => true}}, "new" => true} ' ; ok: '0.0').): Я пытался заставить его работать час или около того, но не мог понять, почему этого не произошло. Нужно ли упоминать, что я новичок в манго? :) – EasyPush

+0

О, и точная команда, которую я запускаю, следующая: battle = Battle.collection.find_and_modify (query: {enemy: current_user._id, submitted: true}, update: {'$ set' => { разрешение: true}},: new => true) – EasyPush

+0

Какую версию mongo вы используете? –