Resque Worker:无效操作符:$oid。

6

一名几天前还在工作的工人因某些原因停止了工作。

Resque日志报告了一个Mongo::OperationFailure异常,错误信息为invalid operator: $oid

class SimilarTargets
  @queue = :similar_queue

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

    ....

  end
end

工作人员在使用rails控制台传递纯字符串时,在Target.find(target_id)上失败了。
在控制台和代码中,Target.find(id)运行正常,但我无法弄清楚为什么这个工作人员类即使在过去一周中也从未更改,仍然会出现错误。
2个回答

8

最近升级了Mongoid吗?该错误表明.find()方法接收到了类似于{"$oid": "[STRING]"}的内容,这是Mongo中Object ID的严格JSON表示形式。

如果你只想快速解决问题,可以采用以下方法:

target_id = target_id["$oid"] unless target_id.is_a?(String)

我也遇到了这个问题,你知道为什么会这样吗?我在使用mongoid对象id创建Resque作业时出现了奇怪的不一致行为。我的应用程序是一个Sinatra应用程序,在一个请求处理程序中,它创建一个新的Resque作业,该作业以mongoid文档的ID作为参数。此作业有效,只需将ID序列化为字符串即可。但是,当此作业完成时,它排队了另一个作业,将相同对象的ID传递给下一个作业,由于某种原因,第二个作业获取了ObjectID的JSON版本,而不仅仅是字符串。两个作业都以相同的方式排队。 - Ibrahim
2
正如MrKurt所说,Moped :: BSON :: ObjectId序列化为JSON为"{"$ oid": "#{to_s}"}"。当Resque将Object Id转储到其有效载荷时,会对ObjectId调用to_json,从而导致在稍后执行作业时存储和编组此内容。 - Jonathan R. Wallace

1
另一个选项是确保在排队Moped :: BSON :: ObjectId时,您明确传递字符串表示形式。例如,
Resque.enqueue(MyJob, @mongoid_instance.class.to_s, @mongoid_instance.id.to_s)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接