Resque Worker: неверный оператор: $oid

Работник, который работал несколько дней назад, по какой-то причине перестал работать.

Журнал resque сообщает об исключении Mongo::OperationFailure с ошибкойinvalid operator: $oid

class SimilarTargets
  @queue = :similar_queue

  def self.perform(target_id)
    source_target = Target.find(target_id)

    ....

  end
end

Рабочий не работает с Target.find(target_id), даже когда прямая строка передается через консоль rails.

Target.find(id) отлично работает в консоли и в других частях кода, и я не могу понять, почему это не работает, хотя рабочий класс никогда не менялся за последнюю неделю.


person w2bro    schedule 17.07.2012    source источник


Ответы (2)


Вы недавно обновляли Mongoid? Ошибка звучит так, как будто метод .find() получает что-то вроде {"$oid": "[STRING]"}, что является строгим JSON-представлением идентификатора объекта для Mongo.

Вы можете обойти это с помощью чего-то вроде этого, если вам просто нужно быстрое решение:

target_id = target_id["$oid"] unless target_id.is_a?(String)
person MrKurt    schedule 17.07.2012
comment
Я тоже столкнулся с этой проблемой, вы знаете, почему это происходит? У меня странное непоследовательное поведение при создании заданий Resque с идентификаторами объектов mongoid. Мое приложение является приложением Sinatra, и в одном обработчике запросов оно создает новое задание Resque, которое принимает идентификатор монгоидного документа в качестве параметра. Это задание работает нормально, идентификатор просто сериализуется как строка. Однако это задание, когда оно завершается, ставит в очередь другое задание, передавая идентификатор того же объекта следующему заданию, и по какой-то причине это второе задание получает JSON-версию ObjectID, а не просто строку. Оба задания ставятся в очередь одинаково. - person Ibrahim; 23.08.2012
comment
Как сказал MrKurt, Moped::BSON::ObjectId сериализуется в JSON как {\$oid\: \#{to_s}\}. Когда Resque сбрасывает идентификатор объекта в свою полезную нагрузку, to_json вызывается для ObjectId, в результате чего он сохраняется и сортируется при последующем выполнении задания. - person Jonathan R. Wallace; 03.04.2013

Другой вариант — убедиться, что при постановке в очередь Moped::BSON::ObjectId вы явно передаете строковое представление. Например.,

Resque.enqueue(MyJob, @mongoid_instance.class.to_s, @mongoid_instance.id.to_s)
person Jonathan R. Wallace    schedule 03.04.2013